001: /* Copyright 2004 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.container.services.information;
007:
008: import java.io.File;
009: import java.io.FileInputStream;
010: import java.util.Properties;
011:
012: import javax.servlet.ServletConfig;
013:
014: import org.apache.pluto.om.common.ObjectID;
015: import org.apache.pluto.om.portlet.PortletApplicationDefinition;
016: import org.apache.pluto.om.portlet.PortletDefinition;
017: import org.apache.pluto.om.portlet.PortletDefinitionList;
018: import org.apache.pluto.om.servlet.WebApplicationDefinition;
019: import org.apache.pluto.services.information.PortalContextProvider;
020: import org.apache.pluto.services.information.StaticInformationProvider;
021: import org.jasig.portal.container.binding.PortletApplicationUnmarshaller;
022: import org.jasig.portal.container.binding.WebApplicationUnmarshaller;
023: import org.jasig.portal.container.om.common.ObjectIDImpl;
024: import org.jasig.portal.container.om.portlet.PortletApplicationDefinitionListImpl;
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027:
028: /**
029: * Implementation of Apache Pluto StaticInformationProvider.
030: * The current implementation gets its data by parsing the web applciation
031: * deployment descriptor (web.xml) and the portlet application deployment
032: * descriptor (portlet.xml) of all installed portlet contexts. Contexts which
033: * contain a valid portlet.xml file in the WEB-INF directory are considered
034: * portlet contexts.
035: * @author Ken Weiner, kweiner@unicon.net
036: * @version $Revision: 35918 $
037: */
038: public class StaticInformationProviderImpl implements
039: StaticInformationProvider {
040: private static final Log log = LogFactory
041: .getLog(StaticInformationProviderImpl.class);
042: private ServletConfig servletConfig = null;
043: private Properties properties = null;
044: private static PortletApplicationDefinitionListImpl portletApplicationDefinitionList = null;
045: private static PortalContextProvider portalContextProvider = null;
046:
047: // StaticInformationProvider methods
048:
049: public PortalContextProvider getPortalContextProvider() {
050: if (portalContextProvider == null)
051: portalContextProvider = new PortalContextProviderImpl();
052: return portalContextProvider;
053: }
054:
055: public PortletDefinition getPortletDefinition(ObjectID portletGUID) {
056:
057: if (portletGUID == null) {
058: throw new IllegalArgumentException(
059: "Cannot get portlet definition for null portletGUID.");
060: }
061:
062: // I think this method should throw an exception,
063: // but Pluto currently defines it to throw no exception. -kweiner
064:
065: String portletDefinitionId = portletGUID.toString();
066: int dotIndex = portletDefinitionId.indexOf(".");
067:
068: if (dotIndex < 0) {
069: throw new IllegalArgumentException(
070: "portletGUID ["
071: + portletGUID
072: + "] was not in required format: portletGUIDs must contain a '.' character.");
073: }
074:
075: String contextName = portletDefinitionId.substring(0, dotIndex);
076: PortletApplicationDefinition portletApplicationDefinition = portletApplicationDefinitionList
077: .get(ObjectIDImpl.createFromString(contextName));
078: PortletDefinition portletDefinition = null;
079: if (portletApplicationDefinition != null) {
080: PortletDefinitionList portletDefinitionList = portletApplicationDefinition
081: .getPortletDefinitionList();
082: portletDefinition = portletDefinitionList.get(ObjectIDImpl
083: .createFromString(portletDefinitionId));
084: }
085: return portletDefinition;
086: }
087:
088: // Additional methods
089:
090: public void init(ServletConfig servletConfig, Properties properties) {
091: this .servletConfig = servletConfig;
092: this .properties = properties;
093: portletApplicationDefinitionList = new PortletApplicationDefinitionListImpl();
094: initPortletDefinitions();
095: }
096:
097: /**
098: * Go through the webapps directory, look for all web.xml and portlet.xml files
099: * for portlet web applications. Then parse these files and create data structures
100: * representing the portlet application definitions and servlet definitions.
101: * This should occur just once as the portlet container starts up.
102: */
103: private void initPortletDefinitions() {
104: String portalDirName = servletConfig.getServletContext()
105: .getRealPath("/"); //root
106: File webappsDir = new File(portalDirName).getParentFile();
107: File[] files1 = webappsDir.listFiles(); // portlet app candidates
108: for (int i = 0; i < files1.length; i++) {
109: File webapp = files1[i];
110: if (webapp.isDirectory()) {
111: File[] files2 = webapp.listFiles(); // WEB-INF candidates
112: for (int j = 0; j < files2.length; j++) {
113: File webinf = files2[j];
114: if (webinf.isDirectory()
115: && webinf.getName().equals("WEB-INF")) {
116: File webXmlFile = null;
117: File portletXmlFile = null;
118: boolean isPortletApp = false;
119: boolean gotWebXml = false;
120: boolean gotPortletXml = false;
121: File[] files3 = webinf.listFiles(); // web.xml and portlet.xml candidates
122: for (int k = 0; k < files3.length; k++) {
123: File file = files3[k];
124: if (file.getName().equals("web.xml")) {
125: gotWebXml = true;
126: webXmlFile = files3[k];
127: } else if (file.getName().equals(
128: "portlet.xml")) {
129: gotPortletXml = true;
130: portletXmlFile = files3[k];
131: }
132: }
133: isPortletApp = gotWebXml && gotPortletXml;
134: if (isPortletApp) {
135: String contextName = resolveUri(files1[i]
136: .getName());
137:
138: String xmlFile = null;
139: log.info("Found portlet application "
140: + contextName);
141:
142: try {
143: // Parse the web.xml file --> WebApplicationDefinition
144: xmlFile = "web.xml";
145: WebApplicationUnmarshaller wau = new WebApplicationUnmarshaller();
146: wau
147: .init(new FileInputStream(
148: webXmlFile),
149: contextName);
150: WebApplicationDefinition webApplicationDefinition = wau
151: .getWebApplicationDefinition();
152:
153: // Parse the portlet.xml file --> PortletApplicationDefinition
154: xmlFile = "portlet.xml";
155: PortletApplicationUnmarshaller pau = new PortletApplicationUnmarshaller();
156: pau.init(new FileInputStream(
157: portletXmlFile), contextName);
158: PortletApplicationDefinition portletApplicationDefinition = pau
159: .getPortletApplicationDefinition(webApplicationDefinition);
160:
161: // Add this PortletApplicationDefinition to the list
162: portletApplicationDefinitionList.add(
163: portletApplicationDefinition
164: .getId().toString(),
165: portletApplicationDefinition);
166: } catch (Exception e) {
167: log.error("Unable to parse " + xmlFile
168: + " for context '"
169: + contextName + "'", e);
170: }
171: }
172: }
173: }
174: }
175: }
176: }
177:
178: /**
179: * Handles resolution of a web module's file system name to its URI identifier.
180: * @param webModule the file system name.
181: * @return the URI part.
182: */
183: private String resolveUri(String webModule) {
184: // The initial portion of the web module prefix used by JBoss.
185: final String INITIAL_TMP_PREFIX = "tmp";
186:
187: // The length of the full web module prefix used by JBoss plus numeric portion).
188: final int FULL_TMP_PREFIX_LEN = INITIAL_TMP_PREFIX.length() + 5;
189:
190: // The file extension for web application archives (including the leading dot).
191: final String WAR_FILE_EXT = ".war";
192:
193: // The length of the file extension for web application archives (including the leading dot).
194: final int WAR_FILE_EXT_LEN = WAR_FILE_EXT.length();
195:
196: // For JBoss compatibility, change webModule from the form
197: // of "tmp12345foo.war" to "foo".
198: int len = webModule.length();
199: if (webModule.endsWith(WAR_FILE_EXT)) {
200: if (webModule.startsWith(INITIAL_TMP_PREFIX)
201: && len > FULL_TMP_PREFIX_LEN + WAR_FILE_EXT_LEN) {
202: webModule = webModule.substring(FULL_TMP_PREFIX_LEN,
203: len - WAR_FILE_EXT_LEN);
204: } else {
205: webModule = webModule.substring(0, len
206: - WAR_FILE_EXT_LEN);
207: }
208: }
209: // else assumed literal.
210: return webModule;
211: }
212: }
|