1 16 package org.apache.cocoon.portal.layout.impl; 17 18 import java.util.ArrayList ; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.Map ; 23 24 import org.apache.avalon.framework.CascadingRuntimeException; 25 import org.apache.avalon.framework.activity.Disposable; 26 import org.apache.avalon.framework.activity.Initializable; 27 import org.apache.avalon.framework.component.Component; 28 import org.apache.avalon.framework.configuration.Configurable; 29 import org.apache.avalon.framework.configuration.Configuration; 30 import org.apache.avalon.framework.configuration.ConfigurationException; 31 import org.apache.avalon.framework.logger.AbstractLogEnabled; 32 import org.apache.avalon.framework.service.ServiceException; 33 import org.apache.avalon.framework.service.ServiceManager; 34 import org.apache.avalon.framework.service.ServiceSelector; 35 import org.apache.avalon.framework.service.Serviceable; 36 import org.apache.avalon.framework.thread.ThreadSafe; 37 import org.apache.cocoon.ProcessingException; 38 import org.apache.cocoon.portal.PortalComponentManager; 39 import org.apache.cocoon.portal.PortalService; 40 import org.apache.cocoon.portal.aspect.AspectDataHandler; 41 import org.apache.cocoon.portal.aspect.AspectDataStore; 42 import org.apache.cocoon.portal.aspect.AspectDescription; 43 import org.apache.cocoon.portal.aspect.impl.DefaultAspectDataHandler; 44 import org.apache.cocoon.portal.aspect.impl.DefaultAspectDescription; 45 import org.apache.cocoon.portal.coplet.CopletFactory; 46 import org.apache.cocoon.portal.event.Event; 47 import org.apache.cocoon.portal.event.EventManager; 48 import org.apache.cocoon.portal.event.LayoutEvent; 49 import org.apache.cocoon.portal.event.Receiver; 50 import org.apache.cocoon.portal.event.impl.FullScreenCopletEvent; 51 import org.apache.cocoon.portal.event.impl.LayoutRemoveEvent; 52 import org.apache.cocoon.portal.layout.CompositeLayout; 53 import org.apache.cocoon.portal.layout.Item; 54 import org.apache.cocoon.portal.layout.Layout; 55 import org.apache.cocoon.portal.layout.LayoutFactory; 56 import org.apache.cocoon.portal.layout.renderer.Renderer; 57 import org.apache.cocoon.portal.profile.ProfileManager; 58 import org.apache.cocoon.util.ClassUtils; 59 60 127 public class DefaultLayoutFactory 128 extends AbstractLogEnabled 129 implements ThreadSafe, 130 Component, 131 LayoutFactory, 132 Configurable, 133 Disposable, 134 Serviceable, 135 Initializable, 136 Receiver { 137 138 protected Map layouts = new HashMap (); 139 140 protected List descriptions = new ArrayList (); 141 142 protected ServiceSelector storeSelector; 143 144 protected ServiceManager manager; 145 146 protected Configuration[] layoutsConf; 147 148 protected static long idCounter = System.currentTimeMillis(); 149 150 153 public void service(ServiceManager manager) throws ServiceException { 154 this.manager = manager; 155 this.storeSelector = (ServiceSelector)this.manager.lookup( AspectDataStore.ROLE+"Selector" ); 156 } 157 158 161 protected void configureLayout(Configuration layoutConf) 162 throws ConfigurationException { 163 DefaultLayoutDescription desc = new DefaultLayoutDescription(); 164 final String name = layoutConf.getAttribute("name"); 165 166 if ( this.layouts.get(name) != null) { 168 throw new ConfigurationException("Layout name must be unique. Double definition for " + name); 169 } 170 desc.setName(name); 171 desc.setClassName(layoutConf.getAttribute("class")); 172 desc.setCreateId(layoutConf.getAttributeAsBoolean("create-id", false)); 173 desc.setItemClassName(layoutConf.getAttribute("item-class", null)); 174 175 final String defaultRenderer = layoutConf.getChild("renderers").getAttribute("default"); 177 desc.setDefaultRendererName(defaultRenderer); 178 179 final Configuration[] rendererConfs = layoutConf.getChild("renderers").getChildren("renderer"); 180 if ( rendererConfs != null ) { 181 boolean found = false; 182 for(int m=0; m < rendererConfs.length; m++) { 183 final String rName = rendererConfs[m].getAttribute("name"); 184 desc.addRendererName(rName); 185 if ( defaultRenderer.equals(rName) ) { 186 found = true; 187 } 188 } 189 if ( !found ) { 190 throw new ConfigurationException("Default renderer '" + defaultRenderer + "' is not configured for layout '" + name + "'"); 191 } 192 } else { 193 throw new ConfigurationException("Default renderer '" + defaultRenderer + "' is not configured for layout '" + name + "'"); 194 } 195 196 final Configuration[] aspectsConf = layoutConf.getChild("aspects").getChildren("aspect"); 198 if (aspectsConf != null) { 199 for(int m=0; m < aspectsConf.length; m++) { 200 AspectDescription adesc = DefaultAspectDescription.newInstance(aspectsConf[m]); 201 desc.addAspectDescription( adesc ); 202 } 203 } 204 PortalService service = null; 206 try { 207 service = (PortalService)this.manager.lookup(PortalService.ROLE); 208 PortalComponentManager pcManager = service.getComponentManager(); 209 210 Iterator rendererIterator = desc.getRendererNames(); 211 while (rendererIterator.hasNext()) { 212 final String rendererName = (String )rendererIterator.next(); 213 Renderer renderer = pcManager.getRenderer( rendererName ); 214 215 Iterator aspectIterator = renderer.getAspectDescriptions(); 216 while (aspectIterator.hasNext()) { 217 final AspectDescription adesc = (AspectDescription) aspectIterator.next(); 218 desc.addAspectDescription( adesc ); 219 } 220 } 221 } catch (ServiceException ce ) { 222 throw new ConfigurationException("Unable to lookup renderer selector.", ce); 223 } finally { 224 this.manager.release( service ); 225 } 226 227 DefaultAspectDataHandler handler = new DefaultAspectDataHandler(desc, this.storeSelector); 229 this.layouts.put(desc.getName(), new Object [] {desc, handler}); 230 this.descriptions.add(desc); 231 } 232 233 236 public void configure(Configuration configuration) 237 throws ConfigurationException { 238 this.layoutsConf = configuration.getChild("layouts").getChildren("layout"); 239 } 240 241 protected void init() { 242 if ( this.layoutsConf != null ) { 245 synchronized (this) { 246 if ( this.layoutsConf != null ) { 247 for(int i=0; i < layoutsConf.length; i++ ) { 248 try { 249 this.configureLayout( layoutsConf[i] ); 250 } catch (ConfigurationException ce) { 251 throw new CascadingRuntimeException("Unable to configure layout.", ce); 252 } 253 } 254 this.layoutsConf = null; 255 } 256 } 257 } 258 } 259 260 263 public void prepareLayout(Layout layout) 264 throws ProcessingException { 265 if ( layout != null ) { 266 267 this.init(); 268 269 final String layoutName = layout.getName(); 270 if ( layoutName == null ) { 271 throw new ProcessingException("Layout '"+layout.getId()+"' has no associated name."); 272 } 273 Object [] o = (Object []) this.layouts.get( layoutName ); 274 275 if ( o == null ) { 276 throw new ProcessingException("LayoutDescription with name '" + layoutName + "' not found."); 277 } 278 DefaultLayoutDescription layoutDescription = (DefaultLayoutDescription)o[0]; 279 280 layout.setDescription( layoutDescription ); 281 layout.setAspectDataHandler((AspectDataHandler)o[1]); 282 283 if ( layout instanceof CompositeLayout ) { 285 CompositeLayout composite = (CompositeLayout)layout; 286 composite.setItemClassName(layoutDescription.getItemClassName()); 287 288 Iterator items = composite.getItems().iterator(); 289 while ( items.hasNext() ) { 290 this.prepareLayout( ((Item)items.next()).getLayout() ); 291 } 292 } 293 } 294 } 295 296 299 public Layout newInstance(String layoutName) 300 throws ProcessingException { 301 this.init(); 302 303 Object [] o = (Object []) this.layouts.get( layoutName ); 304 305 if ( o == null ) { 306 throw new ProcessingException("LayoutDescription with name '" + layoutName + "' not found."); 307 } 308 DefaultLayoutDescription layoutDescription = (DefaultLayoutDescription)o[0]; 309 310 Layout layout = null; 311 try { 312 Class clazz = ClassUtils.loadClass( layoutDescription.getClassName() ); 313 layout = (Layout)clazz.newInstance(); 314 315 } catch (Exception e) { 316 throw new ProcessingException("Unable to create new instance", e ); 317 } 318 319 String id = null; 320 if ( layoutDescription.createId() ) { 321 synchronized (this) { 322 id = layoutName + '-' + idCounter; 323 idCounter += 1; 324 } 325 } 326 layout.initialize( layoutName, id ); 327 layout.setDescription( layoutDescription ); 328 layout.setAspectDataHandler((AspectDataHandler)o[1]); 329 330 if ( layout instanceof CompositeLayout ) { 331 CompositeLayout composite = (CompositeLayout)layout; 332 composite.setItemClassName(layoutDescription.getItemClassName()); 333 } 334 335 PortalService service = null; 336 try { 337 service = (PortalService)this.manager.lookup(PortalService.ROLE); 338 service.getComponentManager().getProfileManager().register(layout); 339 } catch (ServiceException ce) { 340 throw new ProcessingException("Unable to lookup profile manager.", ce); 341 } finally { 342 this.manager.release( service ); 343 } 344 return layout; 345 } 346 347 350 public List getLayoutDescriptions() { 351 this.init(); 352 return this.descriptions; 353 } 354 355 356 359 public void dispose() { 360 if ( this.manager != null ) { 361 EventManager eventManager = null; 362 try { 363 eventManager = (EventManager)this.manager.lookup(EventManager.ROLE); 364 eventManager.unsubscribe( this ); 365 } catch (Exception ignore) { 366 } finally { 368 this.manager.release( eventManager ); 369 } 370 this.manager.release( this.storeSelector ); 371 this.storeSelector = null; 372 this.manager = null; 373 } 374 375 } 376 377 380 public void initialize() throws Exception { 381 EventManager eventManager = null; 382 try { 383 eventManager = (EventManager)this.manager.lookup(EventManager.ROLE); 384 eventManager.subscribe( this ); 385 } finally { 386 this.manager.release( eventManager ); 387 } 388 } 389 390 393 public void inform(LayoutEvent event, PortalService service) { 394 Layout layout = (Layout)event.getTarget(); 395 if ( event instanceof LayoutRemoveEvent ) { 396 try { 397 this.remove( layout ); 398 } catch (ProcessingException pe) { 399 throw new CascadingRuntimeException("Exception during removal.", pe); 400 } 401 } 402 } 403 404 407 public void remove(Layout layout) 408 throws ProcessingException { 409 if ( layout != null ) { 410 this.init(); 411 if ( layout instanceof CompositeLayout ) { 412 final CompositeLayout cl = (CompositeLayout)layout; 413 while ( cl.getItems().size() > 0 ) { 414 final Item i = cl.getItem(0); 415 this.remove( i.getLayout() ); 416 } 417 } 418 Item parent = layout.getParent(); 419 if ( parent != null && parent.getParent() != null) { 420 parent.getParent().removeItem( parent ); 421 } 422 423 PortalService service = null; 424 EventManager eventManager = null; 425 try { 426 service = (PortalService)this.manager.lookup(PortalService.ROLE); 427 ProfileManager profileManager = service.getComponentManager().getProfileManager(); 428 if ( layout instanceof CopletLayout ) { 429 if ( layout.equals(service.getEntryLayout(null)) ) { 431 Event event = new FullScreenCopletEvent(((CopletLayout)layout).getCopletInstanceData(), null); 432 eventManager = (EventManager)this.manager.lookup(EventManager.ROLE); 433 eventManager.send(event); 434 service.getComponentManager().getLinkService().addEventToLink(event); 435 } 436 CopletFactory factory = service.getComponentManager().getCopletFactory(); 437 factory.remove( ((CopletLayout)layout).getCopletInstanceData()); 438 } 439 profileManager.unregister(layout); 440 } catch (ServiceException ce) { 441 throw new ProcessingException("Unable to lookup portal service.", ce); 442 } finally { 443 this.manager.release( service ); 444 this.manager.release(eventManager); 445 } 446 } 447 } 448 } 449 | Popular Tags |