View Javadoc

1   /***
2    *
3    * Copyright 2004 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.pluto.portalImpl.services.portletdefinitionregistry;
18  
19  import java.io.BufferedReader;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.InputStreamReader;
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Vector;
29  
30  import javax.servlet.ServletConfig;
31  import javax.servlet.ServletContext;
32  import javax.servlet.UnavailableException;
33  
34  import org.apache.pluto.om.common.ObjectID;
35  import org.apache.pluto.om.portlet.PortletApplicationDefinition;
36  import org.apache.pluto.om.portlet.PortletApplicationDefinitionList;
37  import org.apache.pluto.om.portlet.PortletDefinition;
38  import org.apache.pluto.portalImpl.om.portlet.impl.PortletApplicationDefinitionImpl;
39  import org.apache.pluto.portalImpl.om.portlet.impl.PortletApplicationDefinitionListImpl;
40  import org.apache.pluto.portalImpl.om.servlet.impl.WebApplicationDefinitionImpl;
41  import org.apache.pluto.portalImpl.util.Properties;
42  import org.apache.pluto.portalImpl.xml.Constants;
43  import org.apache.pluto.portalImpl.xml.XmlParser.EntityResolver;
44  import org.exolab.castor.mapping.Mapping;
45  import org.exolab.castor.mapping.MappingException;
46  import org.exolab.castor.xml.MarshalException;
47  import org.exolab.castor.xml.Unmarshaller;
48  import org.exolab.castor.xml.ValidationException;
49  import org.xml.sax.InputSource;
50  
51  /***
52   * A version of the registry service that obtains data from a ServletContext
53   * rather than trying to scan for portlet applications.
54   *
55   * @version $Rev$ $Date$
56   */
57  public class PortletDefinitionRegistryServiceContextImpl extends PortletDefinitionRegistryService {
58      public static final String DEFAULT_CONTEXTS = "/WEB-INF/data/portletcontexts.txt";
59  
60      public final static String DEFAULT_MAPPING_PORTLETXML = "/WEB-INF/data/xml/portletdefinitionmapping.xml";
61      public final static String DEFAULT_MAPPING_WEBXML = "/WEB-INF/data/xml/servletdefinitionmapping.xml";
62  
63      private static final String CONFIG_MAPPING_PORTLETXML = "mapping.portletxml.configfile";
64      private static final String CONFIG_MAPPING_WEBXML = "mapping.webxml.configfile";
65  
66      //static modifier for hot deploy
67      private static Mapping webXmlMapping;
68      //static modifier for hot deploy
69      private static Mapping portletXmlMapping;
70  
71      //static modifier for hot deploy
72      private static PortletApplicationDefinitionListImpl registry;
73      //static modifier for hot deploy
74      private static Map definitions;
75  
76      public PortletApplicationDefinitionList getPortletApplicationDefinitionList() {
77          return registry;
78      }
79  
80      public PortletDefinition getPortletDefinition(ObjectID id) {
81          return (PortletDefinition) definitions.get(id);
82      }
83  
84      protected void init(ServletConfig config, Properties props) throws Exception {
85          ServletContext context = config.getServletContext();
86          portletXmlMapping = loadMapping(context, props.getString(CONFIG_MAPPING_PORTLETXML, DEFAULT_MAPPING_PORTLETXML));
87          webXmlMapping = loadMapping(context, props.getString(CONFIG_MAPPING_WEBXML, DEFAULT_MAPPING_WEBXML));
88  
89          List contexts = loadDefinitionList(context, DEFAULT_CONTEXTS);
90          registry = new PortletApplicationDefinitionListImpl();
91          for (Iterator i = contexts.iterator(); i.hasNext();) {
92              String contextRoot = (String) i.next();
93              PortletApplicationDefinition portletApp = loadApplicationDefinition(context, contextRoot);
94              registry.add(portletApp);
95          }
96  
97          definitions = new HashMap();
98          for (Iterator i = registry.iterator(); i.hasNext();) {
99              PortletApplicationDefinition application = (PortletApplicationDefinition) i.next();
100 
101             for (Iterator j = application.getPortletDefinitionList().iterator(); j.hasNext();) {
102                 PortletDefinition portlet = (PortletDefinition) j.next();
103                 definitions.put(portlet.getId(), portlet);
104             }
105         }
106     }
107 
108     private Mapping loadMapping(ServletContext context, String path) throws UnavailableException {
109         InputSource source = new InputSource(context.getResourceAsStream(path));
110         Mapping mapping = new Mapping();
111         try {
112             mapping.loadMapping(source);
113         } catch (IOException e) {
114             throw (UnavailableException) new UnavailableException("Error reading mapping " + path).initCause(e);
115         } catch (MappingException e) {
116             throw (UnavailableException) new UnavailableException("Invalid mapping " + path).initCause(e);
117         }
118         return mapping;
119     }
120 
121     private List loadDefinitionList(ServletContext context, String path) throws UnavailableException {
122         InputStream stream = context.getResourceAsStream(path);
123         if (stream == null) {
124             throw new UnavailableException("Unable to load registry " + path);
125         }
126         BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
127         try {
128             try {
129                 String line;
130                 List contexts = new ArrayList();
131                 while ((line = reader.readLine()) != null) {
132                     contexts.add(line.trim());
133                 }
134                 return contexts;
135             } finally {
136                 reader.close();
137             }
138         } catch (IOException e) {
139             throw (UnavailableException) new UnavailableException("Error reading registry from " + path).initCause(e);
140         }
141     }
142 
143     private PortletApplicationDefinition loadApplicationDefinition(ServletContext context, String path) throws UnavailableException {
144         // locate the portlet application's context
145         ServletContext appContext = context.getContext(path);
146         if (appContext == null) {
147             throw new UnavailableException("Unable to access context for " + path);
148         }
149 
150         // load its portlet.xml
151         InputStream stream = appContext.getResourceAsStream("/WEB-INF/portlet.xml");
152     	String contextName = appContext.getServletContextName();
153         if (stream == null) {
154             throw new UnavailableException("The portlet.xml could not be found in context " + contextName + " (" + path + ")");
155         }
156         InputSource source = new InputSource(stream);
157         Unmarshaller unmarshaller;
158         try {
159             unmarshaller = new Unmarshaller(portletXmlMapping);
160             unmarshaller.setEntityResolver(new EntityResolver(Constants.RES_PORTLET_DTDS, Constants.RES_PORTLET_DTD_NAMES));
161         } catch (MappingException e) {
162             throw (UnavailableException) new UnavailableException("Unable to construct unmarshaller for portlet.xml at context " + contextName).initCause(e);
163         }
164         unmarshaller.setIgnoreExtraElements(true);
165         PortletApplicationDefinitionImpl portletApp;
166         try {
167             portletApp = (PortletApplicationDefinitionImpl) unmarshaller.unmarshal(source);
168         } catch (MarshalException e) {
169             throw (UnavailableException) new UnavailableException("Unable to unmarshal portlet.xml from context " + contextName).initCause(e);
170         } catch (ValidationException e) {
171             throw (UnavailableException) new UnavailableException("Unable to validate portlet.xml from context " + contextName).initCause(e);
172         }
173 
174         // load its web.xml
175         stream = appContext.getResourceAsStream("/WEB-INF/web.xml");
176         if (stream == null) {
177             throw new UnavailableException("No web.xml found in context " + contextName);
178         }
179         source = new InputSource(stream);
180         try {
181             unmarshaller = new Unmarshaller(webXmlMapping);
182             unmarshaller.setEntityResolver(new EntityResolver(Constants.RES_WEB_PUBLIC_ID,
183                                                        Constants.RES_WEB_DTD,
184                                                        Constants.RES_WEB_DTD_NAME));
185         } catch (MappingException e) {
186             throw (UnavailableException) new UnavailableException("Unable to construct unmarshaller for web.xml from context " + contextName + ". Error message: " + e.getMessage()).initCause(e);
187         }
188         unmarshaller.setIgnoreExtraElements(true);
189 
190         WebApplicationDefinitionImpl webApp;
191         try {
192             webApp = (WebApplicationDefinitionImpl) unmarshaller.unmarshal(source);
193         } catch (MarshalException e) {
194             throw (UnavailableException) new UnavailableException("Unable to unmarshal web.xml from context " + contextName + ". Error message: " + e.getMessage()).initCause(e);
195         } catch (ValidationException e) {
196             throw (UnavailableException) new UnavailableException("Unable to validate web.xml from context " + contextName + ". Error message: " + e.getMessage()).initCause(e);
197         }
198 
199         Vector structure = new Vector();
200         structure.add(portletApp);
201         structure.add(path);
202 
203         try {
204             webApp.postLoad(structure);
205             webApp.preBuild(structure);
206             webApp.postBuild(structure);
207         } catch (Exception e) {
208             throw (UnavailableException) new UnavailableException("Problem: " + e.getMessage() + ". Context = " + contextName).initCause(e);
209         }
210         return portletApp;
211     }
212  
213     //method added for hot deploy
214     public void postInit() throws Exception
215      {
216      	PortletDefinitionRegistry.setPortletDefinitionRegistryService();
217      }
218 }
219