You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2007/02/13 14:24:08 UTC

svn commit: r506994 - in /cocoon/trunk/blocks/cocoon-portal: cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/event/ cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/event/impl/ cocoon-portal-impl/src/main/resources/org/apache/cocoon/...

Author: cziegeler
Date: Tue Feb 13 05:24:07 2007
New Revision: 506994

URL: http://svn.apache.org/viewvc?view=rev&rev=506994
Log:
Add checks to link converter

Removed:
    cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/event/ConvertedEvent.java
    cocoon/trunk/blocks/cocoon-portal/cocoon-portal-sample/src/main/resources/COB-INF/config/spring/event-converter.xml
Modified:
    cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/event/impl/DefaultEventConverter.java
    cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/resources/org/apache/cocoon/portal/cocoon-portal-components.xml

Modified: cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/event/impl/DefaultEventConverter.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/event/impl/DefaultEventConverter.java?view=diff&rev=506994&r1=506993&r2=506994
==============================================================================
--- cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/event/impl/DefaultEventConverter.java (original)
+++ cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/event/impl/DefaultEventConverter.java Tue Feb 13 05:24:07 2007
@@ -30,7 +30,6 @@
 import org.apache.cocoon.portal.event.Event;
 import org.apache.cocoon.portal.event.EventConverter;
 import org.apache.cocoon.portal.impl.AbstractBean;
-import org.apache.cocoon.util.ClassUtils;
 import org.apache.cocoon.util.HashUtil;
 
 /**
@@ -39,7 +38,13 @@
  * the current user session. Each event is then converted to a string just containing
  * the index of the event in this list. This list is cleared when the session is closed.
  *
- * TODO - What happens if two event classes have the same hash?
+ * Each event consists of its class name and its data. This event converter concatenates both
+ * information to one string. As the class name is usual rather long, this component
+ * can be configured with a mapping from a unique (short) key to the class name.
+ * If no mapping is configured for an event, a hash of the class name is used as the
+ * hash is usually shorter than the class name. We use a hash as we need a reproducable way
+ * of mapping class names for session sharing.
+ * It is advisable to map all event class to custom keys instead of using a hash.
  *
  * @version $Id$
  */
@@ -50,9 +55,9 @@
     protected static final String EVENT_LIST = DefaultEventConverter.class.getName();
 
     /** All factories mapped by a key.
-     * The key is either the hash if the class name or a configured mapping.
+     * The key is either the hash of the class name or a configured mapping.
      * If there is no configured mapping for an event class, the value
-     * is the constructor to construct the event.
+     * is the constructor of the event class to construct the event.
      * If there is a configured mapping, then this map contains two entries:
      * The first entry has the hash of the class name as the key and the value
      * is the configured mapping name. The second entry has the configured mapping
@@ -83,20 +88,33 @@
                 final Constructor c = this.getConstructor(current.getValue().toString());
                 final long hash = HashUtil.hash(current.getValue().toString());
                 final String hashKey = Long.toString(hash);
+                // check for duplicate hash code
+                if ( this.factories.containsKey(hashKey) ) {
+                    throw new PortalRuntimeException("Duplicate hash code (" + hashKey + ") for classes '" + current.getValue() + "' and '" +
+                                                     this.factories.get(this.factories.get(hashKey)) + "'.");
+                }
+                // check for duplicate mapping
+                if ( this.factories.containsKey(current.getKey().toString()) ) {
+                    throw new PortalRuntimeException("Duplicate mapping for key '" + current.getKey() + "'.");
+                }
                 this.factories.put(hashKey, current.getKey().toString());
                 this.factories.put(current.getKey().toString(), c);
             }
         }
     }
 
-    protected Constructor getConstructor(String factory) {
+    /**
+     * Try to get the constructor for a given event class.
+     * The constructor should be a two argument constructor gettint the portal service and the data string.
+     */
+    protected Constructor getConstructor(String eventClass) {
         try {
-            final Class factoryClass = ClassUtils.loadClass(factory);
+            final Class factoryClass = Thread.currentThread().getContextClassLoader().loadClass(eventClass);
             return factoryClass.getConstructor(new Class[] {PortalService.class, String.class});
         } catch (NoSuchMethodException nsme) {
-            throw new PortalRuntimeException("Factory class does not provide required constructor: " + factory, nsme);
+            throw new PortalRuntimeException("Factory class does not provide required constructor: " + eventClass, nsme);
         } catch (ClassNotFoundException cnfe) {
-            throw new PortalRuntimeException("Factory class can't be loaded: " + factory, cnfe);
+            throw new PortalRuntimeException("Factory class can't be loaded: " + eventClass, cnfe);
         }
     }
 
@@ -104,26 +122,31 @@
      * @see org.apache.cocoon.portal.event.EventConverter#encode(org.apache.cocoon.portal.event.Event)
      */
     public String encode(Event event) {
-        final String eventClassName = event.getClass().getName();
         String data = null;
         // if this is a convertable event just return
         // the used factory and the data.
-        if ( data == null && event instanceof ConvertableEvent ) {
+        if ( event instanceof ConvertableEvent ) {
             data = ((ConvertableEvent)event).asString();
         }
         // check if *this* event is convertable
         if ( data != null ) {
+            final String eventClassName = event.getClass().getName();
             final long hash = HashUtil.hash(eventClassName);
             final String hashKey = Long.toString(hash);
             Object o = this.factories.get(hashKey);
             if ( o == null ) {
                 final Constructor c = this.getConstructor(eventClassName);
+                if ( this.getLogger().isWarnEnabled() ) {
+                    this.getLogger().warn("No mapping defined for event class: '" + eventClassName + "'.");
+                }
                 this.factories.put(hashKey, c);
                 o = c;
             }
             if ( o instanceof Constructor ) {
-                return hashKey + ':' + data;
-            } else if ( o instanceof EventConverter ) {
+                if ( !((Constructor)o).getDeclaringClass().getName().equals(eventClassName) ) {
+                    throw new PortalRuntimeException("Duplicate hash code (" + hashKey + ") for classes '" + eventClassName + "' and '" +
+                            ((Constructor)o).getDeclaringClass().getName() + "'.");
+                }
                 return hashKey + ':' + data;
             }
             return o.toString() + ':' + data;
@@ -152,9 +175,9 @@
                 final String hashKey = value.substring(0, pos);
                 final String data = value.substring(pos+1);
                 Object o = this.factories.get(hashKey);
-                // if the value is a constructor or an event converter we simply use it
+                // if the value is a constructor we simply use it
                 // if the value is a string we simply use this string
-                // to lookup the constructor/event converter (another lookup in the map).
+                // to lookup the constructor (another lookup in the map).
                 if ( o instanceof String ) {
                     o = this.factories.get(o);
                 }
@@ -163,18 +186,12 @@
                     try {
                         return (Event)c.newInstance(new Object[] {this.portalService, data});
                     } catch (InstantiationException ie) {
-                        ie.printStackTrace();
                         // we ignore this
                     } catch (InvocationTargetException ite) {
-                        ite.printStackTrace();
                         // we ignore this                    
                     } catch (IllegalAccessException iae) {
-                        iae.printStackTrace();
                         // we ignore this                    
                     }
-                } else if ( o instanceof EventConverter ) {
-                    EventConverter converter = (EventConverter)o;
-                    return converter.decode(data);
                 }
             }
             List list = (List)this.portalService.getUserService().getAttribute(EVENT_LIST);

Modified: cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/resources/org/apache/cocoon/portal/cocoon-portal-components.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/resources/org/apache/cocoon/portal/cocoon-portal-components.xml?view=diff&rev=506994&r1=506993&r2=506994
==============================================================================
--- cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/resources/org/apache/cocoon/portal/cocoon-portal-components.xml (original)
+++ cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/resources/org/apache/cocoon/portal/cocoon-portal-components.xml Tue Feb 13 05:24:07 2007
@@ -32,14 +32,24 @@
       +-->
     <bean name="org.apache.cocoon.portal.event.EventConverter"
           class="org.apache.cocoon.portal.event.impl.DefaultEventConverter"
-          init-method="init" scope="singleton"/>
-  
+          init-method="init" scope="singleton">
+      <!-- Map event class to keys. These keys are used to create the values
+           for the uri if that event is used. If no mapping is found a hash
+           of the event class name is used as default. -->
+      <property name="mappings">
+        <map>
+          <entry key="sizing" value="org.apache.cocoon.portal.event.coplet.CopletInstanceSizingEvent"/>
+          <entry key="lpar" value="org.apache.cocoon.portal.event.layout.LayoutChangeParameterEvent"/>
+        </map>
+      </property>
+    </bean>
+
   <!--+
       | Portal Link Service.
       |
       +-->
     <bean name="org.apache.cocoon.portal.services.LinkService"
-          class="org.apache.cocoon.portal.services.LinkService"
+          class="org.apache.cocoon.portal.services.impl.DefaultLinkService"
           scope="singleton"/>
 
 </beans>