Forum Stats

  • 3,782,552 Users
  • 2,254,664 Discussions
  • 7,880,119 Comments

Discussions

How to build a portlet by BEA API

668596
668596 Member Posts: 48
edited Jan 6, 2009 3:42AM in WebLogic Portal
I want to build one portlet by api,but I don't know how to use api.
I find api doc,some api maybe create a portlet ,for example PortletEntry,PortletDefinition and so all
so,please tell me how can I create a portlet by api,thank you!
«1

Answers

  • 667822
    667822 Member Posts: 36
    Fish,

    Can you provide more information on what you are trying to do? Do you mean the JSR-168 API, or do you want to add a portlet to a page programmatically, or...

    Regards,
    Peter
  • 668596
    668596 Member Posts: 48
    ok,I know JSR168 API,but this API can create a portlet and display in many pages.
    I wonder use bea api not JSR168 API build a portlet,make up a portlet by something,for example PortletDefinition ,it provide some method
    PortletDefinition(LocalizationResource localizationResource, MarkupDefinitionId markupDefinitionId, String contentUri, String backingFile, String definitionLabel, String instanceLabel, boolean forkable, boolean _public, ThemeDefinitionId themeDefinitionId, short titlebarOrientation, boolean defaultMinimized, boolean renderCacheable, int cacheExpires, boolean forkRender, String portletFile, boolean deleted, String helpUri, String editUri, String webAppName)
    and so on,but I don't know how to use this api,so I want to everyone help !
  • 668596
    668596 Member Posts: 48
    I use bea some api like this:
    LocalizationIntersectionId lid = LocalizationIntersectionId.createLocalizationIntersectionId(1234);
    LocalizationResource lr = PortletInstanceInternal.createLocalizationResourceInternal(lid);
    MarkupDefinitionId mId = MarkupDefinitionId.createMarkupDefinitionId(2234);
    ThemeDefinitionId themeId = ThemeDefinitionId.createThemeDefinitionId(3234);
    String contentUri = "/ss/test/test.jsp";
    String portletFile = "1test.portlet";
    PortletDefinition pd = new PortletDefinition(lr, mId, contentUri, null, "lo_1", "loins_1", false, true, themeId, PortletView.ORIENTATION_LEFT, false, true, 1, false, portletFile, false, null, null, ApplicationHelper.getWebAppName(request));
    IPortletDefinitionManager ipd = new PortletDefinitionManagerImpl();
    ipd.createPortletDefinition(new CustomizationContext(request), pd);

    some error is display,but I don't understand what is the mean:
    com.bea.netuix.application.exception.MissingDataException: "The object of type [PortletDefinition] for file [1test.portlet] is invalid, for the following reason: ["The object of type [LocalizationResource] is invalid, for the following reason: ["The field [title] is null or an empty string"]."]."
  • 650850
    650850 Member Posts: 843
    Fish,

    You're getting the error message you included because the objects you are trying to create are not being correctly created in the database.

    For example, your sample code is trying to create a LocalizationIntersectionId with a value of "1234". While the API does let you do that, it is not valid to just assign a random value (like 1234) to an ID; IDs such as this are created and maintained in database tables. When you create an ID that doesn't exist in the database, things get very confused.

    In addition, you are using undocumented (and unsupported) classes and methods, such as PortletInstanceInternal. While these classes do exist, they are not a part of the WLP API and are not designed or intended to be called by developers. Using the internal classes may have serious side-effects that are not apparent from the method name, and internal classes may change at any time without notice- for example, an upgrade to a new version of WLP, or even a bug patch applied to your existing version.

    So, to create a portlet with the supported API, you will need to use various EJBs. For example, to create a LocalizationResource, you would need to use the LocalizationManager EJB's createLocalizationResource() method, as documented at:

    http://download.oracle.com/docs/cd/E13155_01/wlp/docs103/javadoc/com/bea/netuix/application/localization/manager/ILocalizationManager.html

    This method will create a new LocalizationResource in the database, and return an object with a valid LocalizationIntersectionID.

    To create a portlet definition, use the PortletDefinitionManager EJB's createPortletDefintion() method, as documented at:

    http://download.oracle.com/docs/cd/E13155_01/wlp/docs103/javadoc/com/bea/netuix/application/manager/IPortletDefinitionManager.html

    This method will create a portlet definition in the database and return an object with all the appropriate IDs filled out.

    In general, you will need to use the EJBs documented at:

    http://download.oracle.com/docs/cd/E13155_01/wlp/docs103/javadoc/com/bea/netuix/application/manager/package-summary.html

    but the entire API for WLP (version 10.3) is available at:

    http://download.oracle.com/docs/cd/E13155_01/wlp/docs103/javadoc/index.html

    Kevin
  • 667822
    667822 Member Posts: 36
    edited Jan 4, 2009 11:55PM
    Fish,

    Here is some sample code for what Kevin is talking about.

    ---------------------

    LookAndFeelDefinitionManager lafdm= PortalFrameworkManagerHelper.getLookAndFeelDefinitionManager();
    MarkupDefinitionManager mdm= PortalFrameworkManagerHelper.getMarkupDefinitionManager();
    PortletDefinitionManager pdm= PortalFrameworkManagerHelper.getPortletDefinitionManager();

    // SET EACH FIELD OF THE PORTLET
    // NOTE: portletXmlDef is an object from the source of this sample code, replace
    // with the configuration info appropriate for your use case
    String definitionLabel = portletXmlDef.getATTRDEFNLABEL();
    String instanceLabel = portletXmlDef.getATTRINSTANCELABEL();
    String backingFile = portletXmlDef.getATTRBACKINGFILE();
    boolean isPublic = portletXmlDef.getPublic();
    boolean isDefaultMinimized = portletXmlDef.getATTRDEFAULTMINIMIZED();
    boolean isRenderCacheable = portletXmlDef.getATTRCACHEABLE();
    int cacheExpires = new Long(portletXmlDef.getATTRCACHEEXPIRES()).intValue();
    boolean isForkRender = portletXmlDef.getATTRFORKRENDER();
    boolean isForkable = portletXmlDef.getATTRFORKABLE();
    String contentUri = portletXmlDef.getATTRCONTENTURI();
    String helpUri = portletXmlDef.getATTRHELPURI();
    String editUri = portletXmlDef.getATTREDITURI();
    String webappName = portletXmlDef.getATTRWEBAPP();
    String markupName = portletXmlDef.getATTRMARKUPDEFN(); // as in "/portlets/includes/Quote.portlet"
    MarkupDefinition markupDef = mdm.getMarkupDefinition(cc, markupName, webappName);
    String themeFile = portletXmlDef.getATTRTHEMELABEL();
    ThemeDefinition themeDef = lafdm.getThemeDefinitionFromFile(cc, themeFile, webappName);
    ThemeDefinitionId themeDefinitionId = null;
    if (themeDef != null)
    {
    themeDefinitionId = themeDef.getThemeDefinitionId();
    }
    short orientShort = PortletView.ORIENTATION_TOP;

    // CREATE THE OBJECTS IN THE DB

    LocalizationResource locResource = new LocalizationResource(Locale.US, "My Title", "My Description");
    PortletDefinition portletDefn= new PortletDefinition(locResource, markupDef.getMarkupDefinitionId(),
    contentUri, backingFile, definitionLabel, instanceLabel, isForkable, isPublic, themeDefinitionId,
    orientShort, isDefaultMinimized, isRenderCacheable, cacheExpires, isForkRender, null, false,
    helpUri, editUri, webappName);
    pdm.createPortletDefinition(cc, portletDefn);

    ---------------------



    ...where the manager lookups in the beginning follow this pattern:

    ---------------------


    LookAndFeelDefinitionManagerHome home =
    (LookAndFeelDefinitionManagerHome)PortableRemoteObject.narrow(
    new InitialContext().lookup(ApplicationHelper.getVersionedAppName() + "." + LookAndFeelDefinitionManagerHome.LOOKUP_NAME),
    LookAndFeelDefinitionManagerHome.class );
    LookAndFeelDefinitionManager lafdm = home.create();

    ---------------------
  • 668596
    668596 Member Posts: 48
    ok,I write some code like this:
    LocalizationLocale lll = new LocalizationLocale(request.getLocale());
    LocalizationResource lr = new LocalizationResource(lll, "visitorTool", "test this portlet", "portlet", "PORTAL");
    ILocalizationManager ilm = new LocalizationManagerImpl();
    LocalizationResource nlr = ilm.createLocalizationResource(lr);
    MarkupDefinitionId mId = MarkupDefinitionId.createMarkupDefinitionId(2234);
    ThemeDefinitionId themeId = ThemeDefinitionId.createThemeDefinitionId(3234);
    String contentUri = "/visitorTools/visitorMenu.jsp";
    String portletFile = "/visitorTools/visitorMenu.portlet";
    PortletDefinition pd = new PortletDefinition(nlr, mId, contentUri, null, "visitorTools_2fresources_2fvisitorTools_2eportlet", "visitorTools_2fresources_2fvisitorTools_2eportlet", false, true, themeId, PortletView.ORIENTATION_LEFT, false, true, 1, false, portletFile, false, null, null, ApplicationHelper.getWebAppName(request));
    IPortletDefinitionManager ipd = new PortletDefinitionManagerImpl();
    ipd.createPortletDefinition(customizationContext, pd);

    then the console display some error,I think the error is PortletDefinitionId is null,but the PortletDefinitionId is a sequence I don't change it:
    javax.ejb.EJBException: SQL Error while trying to create portlet definition: SQL [insert into PF_PORTLET_DEFINITION ( PORTLET_DEFINITION_ID, MARKUP_DEFINITION_ID, IS_FORKABLE, PORTLET_LABEL, CONTENT_URI, BACKING_FILE, IS_PUBLIC, FORK_RENDER, IS_CACHEABLE, CACHE_EXPIRES, PORTLET_FILE, IS_PORTLET_FILE_DELETED, HELP_URI, EDIT_URI, WEBAPP_NAME, WSRP_PROPERTIES_MODE) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)] portletDefinition [
    PortletDefinition::
    PortletDefinitionId = null
    LocalizationResource:
    IntersectionId: 4001
    title = visitorTool
    description = test this portlet
    type = portlet
    application = PORTAL
    locale =
    LocalizationLocale:
    localizationLocaleId = [2001]
    locale = [zh_CN]
    encoding = [UTF-8]
    markupDefinitionId = 2234
    contentUri = /visitorTools/visitorMenu.jsp
    backingFile = null
    definitionLabel = visitorTools_2fresources_2fvisitorTools_2eportlet
    forkable = false
    public = true
    renderCacheable = true
    cacheExpires = 1
    forkRender = false
    portletFile = /visitorTools/visitorMenu.portlet
    deleted = false
    helpUri = null
    editUri = null
    webAppName = sss]
    database error code [85,000] SQL state [ZZE00].; nested exception is: java.sql.SQLException: Referential Integrity Violation. WEBLOGIC.PF_PORTLET_DEFINITION references WEBLOGIC.PF_MARKUP_DEFINITION
    java.sql.SQLException: Referential Integrity Violation. WEBLOGIC.PF_PORTLET_DEFINITION references WEBLOGIC.PF_MARKUP_DEFINITION
    at com.pointbase.net.netJDBCPrimitives.handleResponse(Unknown Source)
    at com.pointbase.net.netJDBCPrimitives.handlePrimitiveResponse(Unknown Source)
    at com.pointbase.net.netJDBCPreparedStatement.executeUpdate(Unknown Source)
    at weblogic.jdbc.wrapper.PreparedStatement.executeUpdate(PreparedStatement.java:159)
    at com.bea.netuix.application.manager.persistence.jdbc.PortletDefinitionDelegate.createPortletDefinitionInternal(PortletDefinitionDelegate.java:1694)
    at com.bea.netuix.application.manager.persistence.jdbc.PortletDefinitionDelegate.createPortletDefinition(PortletDefinitionDelegate.java:1123)
    at com.bea.netuix.application.manager.persistence.jdbc.PortletDefinitionManagerImpl.createPortletDefinition(PortletDefinitionManagerImpl.java:412)
    at com.Test.createPortletDefinition(Test.java:60)
    at com.hp.visitor.forms.logonForm.logon(logonForm.java:102)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:129)
    at netbank.web.jsf.webapp.listener.GlobalActionListener.processAction(GlobalActionListener.java:37)
    at org.apache.beehive.netui.pageflow.faces.internal.PageFlowActionListener.processAction(PageFlowActionListener.java:60)
    at javax.faces.component.UICommand.broadcast(UICommand.java:106)
    at javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:94)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:168)
    at org.apache.myfaces.lifecycle.LifecycleImpl.invokeApplication(LifecycleImpl.java:343)
    at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:86)
    at com.bea.portlet.adapter.faces.FacesContentStubImpl.processAction(FacesContentStubImpl.java:246)
    at com.bea.netuix.servlets.controls.content.FacesContent.raiseFacesAction(FacesContent.java:257)
    at com.bea.netuix.servlets.controls.content.FacesContent.handlePostbackData(FacesContent.java:195)
    at com.bea.netuix.nf.ControlLifecycle$2.visit(ControlLifecycle.java:180)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:324)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walkRecursive(ControlTreeWalker.java:334)
    at com.bea.netuix.nf.ControlTreeWalker.walk(ControlTreeWalker.java:130)
    at com.bea.netuix.nf.Lifecycle.processLifecycles(Lifecycle.java:395)
    at com.bea.netuix.nf.Lifecycle.processLifecycles(Lifecycle.java:361)
    at com.bea.netuix.nf.Lifecycle.processLifecycles(Lifecycle.java:352)
    at com.bea.netuix.nf.Lifecycle.runInbound(Lifecycle.java:184)
    at com.bea.netuix.nf.Lifecycle.run(Lifecycle.java:159)
    at com.bea.netuix.servlets.manager.UIServlet.runLifecycle(UIServlet.java:252)
    at com.bea.netuix.servlets.manager.UIServlet.doPost(UIServlet.java:185)
    at com.bea.netuix.servlets.manager.UIServlet.service(UIServlet.java:141)
    at com.bea.netuix.servlets.manager.SingleFileServlet.service(SingleFileServlet.java:251)
    at com.bea.netuix.servlets.manager.PortalServlet.service(PortalServlet.java:686)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
    at com.bea.portal.tools.servlet.http.HttpContextFilter.doFilter(HttpContextFilter.java:60)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
    at com.bea.p13n.servlets.PortalServletFilter.doFilter(PortalServletFilter.java:336)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
    at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3502)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(Unknown Source)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2186)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2092)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
  • 650850
    650850 Member Posts: 843
    Fish,

    The problem you are running into now is caused by your creating IDs directly (such as MarkupDefinitionId.createMarkupDefinitionId(2234)) instead of using the appropriate API methods for object creation, and by your use of internal classes, such as LocalizationManagerImpl.

    If classes are not documented in the javadoc at

    http://download.oracle.com/docs/cd/E13155_01/wlp/docs103/javadoc/index.html

    they are not safe to use. It will not work to create any ID object by giving it a static value-- you will end up with referential integrity violations like you are running into.

    The sample code that Peter posted will work for you; just replace the portletXmlDef.XXX calls with appropriate values for your needs. To get references to the EJBs, such as LocalizationManager, use the PortalFrameworkManagerHelper class, as Peter's example code used.

    Kevin
  • 668596
    668596 Member Posts: 48
    I can't find the api PortalFrameworkManagerHelper,where is it?

    portletXmlDef object when I use it that I must create it right?so if I use it I have to set some properties,but PortletDefinitionId is a augomatic build by sequence,I find the PortletDefinitionId is null,maybe the application never connect the datasource
  • 667822
    667822 Member Posts: 36
    Hi Fish - I grabbed that code from a utility I wrote. I didn't provide all of the code references.

    PortalFrameworkManagerHelper - it is an internal class, so not available. Instead of providing it, I alluded in the second code snippet that those methods are easy to recreate.

    portletXmlDef - similar to above. I left it in the sample code, but didn't intend for you to create such an object. Just set the fields directly, like:

    boolean isPublic = true;
    boolean isDefaultMinimized = false;
    boolean isRenderCacheable = true;
    int cacheExpires = 60;
    boolean isForkRender = false;
  • 667822
    667822 Member Posts: 36
    Hi Fish,

    The more I think about this, the more I wonder what your use case is. There may be a much easier solution to what you are trying to do.

    - Are you trying to add an existing portlet to a page (a new instance, in WLP terminology), or
    - Are you creating distinct portlets (a new library definition, in WLP terminology). Why?

    Can you provide more information on the use case? In many cases, #2 can be solved with instance level customizations (title localization, preferences) instead of creating entirely new portlet definitions.

    I ask because we have seen customers create portals with many thousands of portlets that all basically do the same thing. They just differ in some configuration metadata. Using portlet preferences are a much better solution in these cases.

    Regards,
    Peter
This discussion has been closed.