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
67 private static Mapping webXmlMapping;
68
69 private static Mapping portletXmlMapping;
70
71
72 private static PortletApplicationDefinitionListImpl registry;
73
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
145 ServletContext appContext = context.getContext(path);
146 if (appContext == null) {
147 throw new UnavailableException("Unable to access context for " + path);
148 }
149
150
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
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
214 public void postInit() throws Exception
215 {
216 PortletDefinitionRegistry.setPortletDefinitionRegistryService();
217 }
218 }
219