1 16 package org.apache.cocoon.portal.pluto.om; 17 18 import java.io.File ; 19 import java.io.FileInputStream ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 import java.util.Vector ; 24 import java.util.List ; 25 import java.util.Arrays ; 26 import java.util.zip.ZipFile ; 27 import java.util.zip.ZipEntry ; 28 import java.net.URL ; 29 30 import javax.servlet.ServletConfig ; 31 import javax.servlet.ServletContext ; 32 33 import org.apache.avalon.framework.activity.Disposable; 34 import org.apache.avalon.framework.activity.Initializable; 35 import org.apache.avalon.framework.context.Context; 36 import org.apache.avalon.framework.context.ContextException; 37 import org.apache.avalon.framework.context.Contextualizable; 38 import org.apache.avalon.framework.logger.AbstractLogEnabled; 39 import org.apache.avalon.framework.service.ServiceException; 40 import org.apache.avalon.framework.service.ServiceManager; 41 import org.apache.avalon.framework.service.Serviceable; 42 import org.apache.cocoon.components.source.SourceUtil; 43 import org.apache.cocoon.portal.PortalService; 44 import org.apache.cocoon.servlet.CocoonServlet; 45 import org.apache.excalibur.source.Source; 46 import org.apache.excalibur.source.SourceResolver; 47 import org.apache.excalibur.xml.EntityResolver; 48 import org.apache.pluto.om.common.ObjectID; 49 import org.apache.pluto.om.entity.PortletApplicationEntityList; 50 import org.apache.pluto.om.entity.PortletApplicationEntityListCtrl; 51 import org.apache.pluto.om.portlet.PortletApplicationDefinitionList; 52 import org.apache.pluto.om.portlet.PortletDefinition; 53 import org.exolab.castor.mapping.Mapping; 54 import org.exolab.castor.xml.Unmarshaller; 55 import org.xml.sax.InputSource ; 56 57 64 public class PortletDefinitionRegistryImpl 65 extends AbstractLogEnabled 66 implements PortletDefinitionRegistry, Contextualizable, Initializable, Serviceable, Disposable { 67 68 private static final String WEB_XML = "WEB-INF/web.xml"; 69 private static final String PORTLET_XML = "WEB-INF/portlet.xml"; 70 71 72 public static final String PORTLET_MAPPING = "resource://org/apache/cocoon/portal/pluto/om/portletdefinitionmapping.xml"; 73 74 75 public static final String WEBXML_MAPPING = "resource://org/apache/cocoon/portal/pluto/om/servletdefinitionmapping.xml"; 76 77 78 protected Context context; 79 80 81 protected ServiceManager manager; 82 83 84 protected PortletApplicationEntityListImpl portletApplicationEntities = new PortletApplicationEntityListImpl(this); 85 86 protected PortletApplicationDefinitionListImpl registry = new PortletApplicationDefinitionListImpl(); 89 90 protected Map portletsKeyObjectId = new HashMap (); 91 92 protected String contextName; 93 94 95 protected EntityResolver resolver; 96 97 98 protected PortalService service; 99 100 103 public void contextualize(Context context) throws ContextException { 104 this.context = context; 105 } 106 107 110 public void service(ServiceManager manager) 111 throws ServiceException { 112 this.manager = manager; 113 this.resolver = (EntityResolver) this.manager.lookup(EntityResolver.ROLE); 114 this.service = (PortalService) this.manager.lookup(PortalService.ROLE); 115 } 116 117 120 public void dispose() { 121 if ( this.manager != null ) { 122 this.manager.release(this.resolver); 123 this.resolver = null; 124 this.manager.release(this.service); 125 this.service = null; 126 this.manager = null; 127 } 128 this.context = null; 129 } 130 131 134 public void initialize() throws Exception { 135 if ( this.getLogger().isDebugEnabled() ) { 136 this.getLogger().debug("Initializing PortletDefinitionRegistry"); 137 } 138 ServletConfig servletConfig = (ServletConfig ) this.context.get(CocoonServlet.CONTEXT_SERVLET_CONFIG); 139 140 ServletContext servletContext = servletConfig.getServletContext(); 141 142 SourceResolver resolver = null; 143 144 try { 145 resolver = (SourceResolver)this.manager.lookup(SourceResolver.ROLE); 146 Mapping mappingPortletXml = new Mapping(); 147 Mapping mappingWebXml = new Mapping(); 148 Source source = null; 149 try { 150 source = resolver.resolveURI(PORTLET_MAPPING); 151 152 mappingPortletXml.loadMapping(SourceUtil.getInputSource(source)); 153 } finally { 154 resolver.release(source); 155 } 156 try { 157 source = resolver.resolveURI(WEBXML_MAPPING); 158 159 mappingWebXml.loadMapping(SourceUtil.getInputSource(source)); 160 } finally { 161 resolver.release(source); 162 } 163 164 String baseWMDir = servletContext.getRealPath(""); 165 166 if (baseWMDir != null) { 167 if (baseWMDir.endsWith(File.separator)) { 169 baseWMDir = baseWMDir.substring(0, baseWMDir.length() - 1); 170 } 171 int lastIndex = baseWMDir.lastIndexOf(File.separatorChar); 173 this.contextName = baseWMDir.substring(lastIndex + 1); 174 baseWMDir = baseWMDir.substring(0, lastIndex + 1); 175 if (this.getLogger().isDebugEnabled()) { 176 this.getLogger().debug("servletContext.getRealPath('') =" + 177 servletContext.getRealPath("")); 178 this.getLogger().debug("baseWMDir = " + baseWMDir); 179 } 180 this.load(baseWMDir, mappingPortletXml, mappingWebXml); 181 } else { 182 if (this.getLogger().isWarnEnabled()) { 183 this.getLogger().warn("Only local portlets are supported when deployed as a war"); 184 this.contextName = "local"; 185 loadLocal(mappingPortletXml, mappingWebXml); 186 } 187 } 188 189 } catch (Exception e) { 190 this.getLogger().error("Error during initialization of registry.", e); 191 } finally { 192 this.manager.release(resolver); 193 } 194 195 ((PortletApplicationEntityListCtrl)this.portletApplicationEntities).add("cocoon"); 196 } 197 198 201 public PortletApplicationDefinitionList getPortletApplicationDefinitionList() { 202 return registry; 203 } 204 205 208 public PortletDefinition getPortletDefinition(ObjectID id) { 209 return (PortletDefinition)portletsKeyObjectId.get(id); 210 } 211 212 protected void load(String baseWMDir, Mapping portletXMLMapping, Mapping webXMLMapping) 213 throws Exception { 214 File f = new File (baseWMDir); 215 String [] entries = f.list(); 216 List entryList = Arrays.asList(entries); 217 for (int i=0; i<entries.length; i++) { 218 File entry = new File (baseWMDir+entries[i]); 219 if ( this.getLogger().isDebugEnabled() ) { 220 this.getLogger().debug("Searching file: " + entry); 221 } 222 if (entry.isDirectory()) { 223 loadWebApp(baseWMDir, entries[i], portletXMLMapping, webXMLMapping); 224 } else if (entry.isFile()) { 225 String name = entry.getName(); 226 int index = name.lastIndexOf(".war"); 227 if (index > 0 && name.endsWith(".war")) { 228 String webModule = name.substring(0, index); 229 if (!entryList.contains(webModule)) { 230 loadWar(entry, webModule, portletXMLMapping, webXMLMapping); 231 } 232 } 233 } 234 } 235 } 236 237 private void loadLocal(Mapping portletXMLMapping, Mapping webXMLMapping) throws Exception { 238 ServletConfig config = 239 (ServletConfig )this.context.get(CocoonServlet.CONTEXT_SERVLET_CONFIG); 240 if (config == null) { 241 if (this.getLogger().isDebugEnabled()) { 242 this.getLogger().debug("Unable to locate servlet config"); 243 } 244 return; 245 } 246 ServletContext servletContext = config.getServletContext(); 247 URL url = servletContext.getResource("/" + PORTLET_XML); 248 if (url != null) { 249 InputSource portletSource = new InputSource (url.openStream()); 250 portletSource.setSystemId(url.toExternalForm()); 251 252 url = servletContext.getResource("/" + WEB_XML); 253 InputSource webSource = null; 254 if (url != null) { 255 webSource = new InputSource (url.openStream()); 256 webSource.setSystemId(url.toExternalForm()); 257 } 258 else { 259 webSource = new InputSource (); 260 webSource.setSystemId("no web.xml!"); 261 } 262 263 load(portletSource, webSource, this.contextName, portletXMLMapping, webXMLMapping); 264 } 265 } 266 267 private void loadWar(File warFile, String webModule, Mapping portletXMLMapping, 268 Mapping webXMLMapping) throws Exception { 269 if (this.getLogger().isDebugEnabled()) { 270 this.getLogger().debug("Searching war " + warFile.getName()); 271 } 272 InputSource portletSource; 273 InputSource webSource; 274 try { 275 ZipFile war = new ZipFile (warFile); 276 ZipEntry entry = war.getEntry(PORTLET_XML); 277 if (entry != null) { 278 portletSource = new InputSource (war.getInputStream(entry)); 279 portletSource.setSystemId("/" + PORTLET_XML); 280 entry = war.getEntry(WEB_XML); 281 if (entry != null) { 282 webSource = new InputSource (war.getInputStream(entry)); 283 webSource.setSystemId("/" + WEB_XML); 284 } else { 285 webSource = new InputSource (); 286 webSource.setSystemId("no web.xml!"); 287 } 288 load(portletSource, webSource, webModule, portletXMLMapping, webXMLMapping); 289 } 290 } catch (Exception e) { 291 if (this.getLogger().isDebugEnabled()) { 292 this.getLogger().debug("Unable to inspect war " + warFile.getName() +". " + 293 e. getMessage()); 294 } 295 } 296 } 297 298 private void loadWebApp(String baseDir, String webModule, Mapping portletXMLMapping, 299 Mapping webXMLMapping) throws Exception { 300 String directory = baseDir + webModule + File.separatorChar + "WEB-INF" + File.separatorChar; 301 if (this.getLogger().isDebugEnabled()) { 302 this.getLogger().debug("Searching in directory: " + directory); 303 } 304 305 File portletXml = new File (directory + "portlet.xml"); 306 File webXml = new File (directory + "web.xml"); 307 308 if (portletXml.exists()) { if (this.getLogger().isDebugEnabled()) { 312 this.getLogger().debug("Loading the following Portlet Applications XML files..." + 313 portletXml + 314 ", " + 315 webXml); 316 } 317 318 InputSource portletSource = new InputSource (new FileInputStream (portletXml)); 319 portletSource.setSystemId(portletXml.toURL().toExternalForm()); 320 InputSource webSource = null; 321 322 if (webXml.exists()) { 323 webSource = new InputSource (new FileInputStream (webXml)); 324 webSource.setSystemId(webXml.toURL().toExternalForm()); 325 } 326 327 load(portletSource, webSource, webModule, portletXMLMapping, webXMLMapping); 328 } 329 } 330 331 private void load(InputSource portletXml, InputSource webXml, String webModule, 332 Mapping portletXMLMapping, Mapping webXMLMapping) throws Exception { 333 if (this.getLogger().isDebugEnabled()) { 334 this.getLogger().debug("Loading the following Portlet Applications XML files..." + 335 portletXml.getSystemId() + 336 ", " + 337 webXml.getSystemId()); 338 } 339 340 Unmarshaller unmarshaller = new Unmarshaller(portletXMLMapping); 341 unmarshaller.setIgnoreExtraElements(true); 342 unmarshaller.setEntityResolver(this.resolver); 343 unmarshaller.setValidation(false); 344 PortletApplicationDefinitionImpl portletApp = 345 (PortletApplicationDefinitionImpl) unmarshaller.unmarshal(portletXml); 346 347 WebApplicationDefinitionImpl webApp = null; 348 349 if (webXml.getByteStream() != null) { 350 unmarshaller = new Unmarshaller(webXMLMapping); 351 unmarshaller.setIgnoreExtraElements(true); 352 unmarshaller.setEntityResolver(this.resolver); 353 unmarshaller.setValidation(false); 354 webApp = (WebApplicationDefinitionImpl) unmarshaller.unmarshal(webXml); 355 356 Vector structure = new Vector (); 357 structure.add(portletApp); 358 structure.add("/" + webModule); 359 360 webApp.postLoad(structure); 361 362 webApp.preBuild(structure); 364 365 webApp.postBuild(structure); 366 } else { 367 this.getLogger().info("no web.xml..."); 368 369 Vector structure = new Vector (); 370 structure.add("/" + webModule); 371 structure.add(null); 372 structure.add(null); 373 374 portletApp.postLoad(structure); 375 376 portletApp.preBuild(structure); 377 378 portletApp.postBuild(structure); 379 380 this.getLogger().debug("portlet.xml loaded"); 381 } 382 383 this.registry.add(portletApp); 384 385 this.getLogger().debug("Portlet added to registry"); 386 387 final Iterator portlets = portletApp.getPortletDefinitionList().iterator(); 389 while (portlets.hasNext()) { 390 final PortletDefinition portlet = (PortletDefinition) portlets.next(); 391 portletsKeyObjectId.put(portlet.getId(), portlet); 392 393 if (this.contextName.equals(webModule)) { 394 ((PortletDefinitionImpl) portlet).setLocalPortlet(true); 395 } 396 ((PortletDefinitionImpl) portlet).setPortletClassLoader(Thread.currentThread() 397 .getContextClassLoader()); 398 } 399 } 400 401 404 public PortletApplicationEntityList getPortletApplicationEntityList() { 405 return this.portletApplicationEntities; 406 } 407 408 411 public PortalService getPortalService() { 412 return this.service; 413 } 414 415 } 416 | Popular Tags |