You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2010/05/16 21:31:20 UTC

svn commit: r944898 - in /ofbiz/trunk/framework/widget/src/org/ofbiz/widget: WidgetFactory.java WidgetLoader.java screen/ModelScreenWidget.java

Author: adrianc
Date: Sun May 16 19:31:19 2010
New Revision: 944898

URL: http://svn.apache.org/viewvc?rev=944898&view=rev
Log:
Converted screen widget sub-widget creation over to the factory pattern. Users can create their own sub-widgets to augment or replace the existing ones.

Added:
    ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetFactory.java   (with props)
    ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetLoader.java   (with props)
Modified:
    ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java

Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetFactory.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetFactory.java?rev=944898&view=auto
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetFactory.java (added)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetFactory.java Sun May 16 19:31:19 2010
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.widget;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import javolution.util.FastMap;
+
+import org.ofbiz.base.util.Assert;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilGenerics;
+import org.ofbiz.widget.screen.IterateSectionWidget;
+import org.ofbiz.widget.screen.ModelScreen;
+import org.ofbiz.widget.screen.ModelScreenWidget;
+import org.w3c.dom.Element;
+
+/**
+ * Screen widget factory.<p>Applications can add their own widget implementations
+ * to the factory by calling the <code>registerXxx(...)</code> methods.</p>
+ */
+public class WidgetFactory {
+
+    public static final String module = WidgetFactory.class.getName();
+    protected static final Map<String, Constructor<? extends ModelScreenWidget>> screenWidgets = FastMap.newInstance();
+
+    static {
+        loadStandardWidgets();
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        Iterator<WidgetLoader> widgetLoaders = ServiceLoader.load(WidgetLoader.class, loader).iterator();
+        while (widgetLoaders.hasNext()) {
+            try {
+                WidgetLoader widgetLoader = widgetLoaders.next();
+                widgetLoader.loadWidgets();
+            } catch (Exception e) {
+                Debug.logError(e, module);
+            }
+        }
+    }
+
+    /**
+     * Returns a <code>ModelScreenWidget</code> instance that implements the specified
+     * XML element.
+     * 
+     * @param modelScreen The containing screen for the widget
+     * @param element The widget XML element
+     * @return a <code>ModelScreenWidget</code> instance that implements the specified
+     * XML element
+     * @throws IllegalArgumentException
+     */
+    public static ModelScreenWidget getModelScreenWidget(ModelScreen modelScreen, Element element) {
+        Assert.notNull("modelScreen", modelScreen, "element", element);
+        Constructor<? extends ModelScreenWidget> widgetConst = screenWidgets.get(element.getTagName());
+        if (widgetConst == null) {
+            throw new IllegalArgumentException("ModelScreenWidget class not found for element " + element.getTagName());
+        }
+        try {
+            return widgetConst.newInstance(modelScreen, element);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(e.getMessage() + " for element " + element.getTagName());
+        }
+    }
+
+    /**
+     * Loads the standard OFBiz screen widgets.
+     */
+    protected static void loadStandardWidgets() {
+        for (Class<?> clz: ModelScreenWidget.class.getClasses()) {
+            try {
+                // Subclass of ModelScreenWidget and non-abstract
+                if (ModelScreenWidget.class.isAssignableFrom(clz) && (clz.getModifiers() & Modifier.ABSTRACT) == 0) {
+                    if (ModelScreenWidget.class.isAssignableFrom(clz)) {
+                        try {
+                            Field field = clz.getField("TAG_NAME");
+                            Object fieldObject = field.get(null);
+                            if (fieldObject != null) {
+                                Class<? extends ModelScreenWidget> widgetClass = UtilGenerics.cast(clz);
+                                registerScreenWidget(fieldObject.toString(), widgetClass);
+                            }
+                        } catch (Exception e) {}
+                    }
+                }
+            } catch (Exception e) {
+                Debug.logError(e, module);
+            }
+        }
+        try {
+            registerScreenWidget("iterate-section", IterateSectionWidget.class);
+        } catch (Exception e) {
+            Debug.logError(e, module);
+        }
+    }
+
+    /**
+     * Registers a screen sub-widget with the factory. If a tag name is already
+     * registered, the new widget replaces the existing one.<p>The class supplied
+     * to the method must have a public two-argument constructor that takes a
+     * <code>ModelScreen</code> instance and an <code>Element</code> instance.</p>
+     * 
+     * @param tagName The XML element tag name for this widget
+     * @param widgetClass The class that implements the widget element
+     * @throws SecurityException
+     * @throws NoSuchMethodException
+     */
+    public static void registerScreenWidget(String tagName, Class<? extends ModelScreenWidget> widgetClass) throws SecurityException, NoSuchMethodException {
+        Assert.notNull("tagName", tagName, "widgetClass", widgetClass);
+        screenWidgets.put(tagName, widgetClass.getConstructor(ModelScreen.class, Element.class));
+        if (Debug.verboseOn()) {
+            Debug.logVerbose("Registered " + widgetClass.getName() + " with tag name " + tagName, module);
+        }
+    }
+
+    private WidgetFactory() {}
+}

Propchange: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetLoader.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetLoader.java?rev=944898&view=auto
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetLoader.java (added)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetLoader.java Sun May 16 19:31:19 2010
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.ofbiz.widget;
+
+/**
+ *  A service that registers screen widget classes with the screen widget factory.
+ *  Applications implement this interface to add their widget implementations
+ *  to the OFBiz framework.<p>Implementations must have their class names
+ *  in the <code>META-INF/service/org.ofbiz.widget.WidgetLoader</code> file.</p> 
+ */
+public interface WidgetLoader {
+
+    /**
+     * Registers screen widgets with the widget factory.<p>Implementations register
+     * screen widget classes by calling the <code>WidgetFactory registerXxxx</code>
+     * methods.</p>
+     */
+    void loadWidgets();
+
+}

Propchange: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetLoader.java
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/WidgetLoader.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java?rev=944898&r1=944897&r2=944898&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/screen/ModelScreenWidget.java Sun May 16 19:31:19 2010
@@ -45,6 +45,7 @@ import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.GenericEntityException;
 import org.ofbiz.entity.GenericValue;
 import org.ofbiz.widget.ModelWidget;
+import org.ofbiz.widget.WidgetFactory;
 import org.ofbiz.widget.WidgetWorker;
 import org.ofbiz.widget.form.FormFactory;
 import org.ofbiz.widget.form.FormStringRenderer;
@@ -83,45 +84,8 @@ public abstract class ModelScreenWidget 
     public static List<ModelScreenWidget> readSubWidgets(ModelScreen modelScreen, List<? extends Element> subElementList) {
         List<ModelScreenWidget> subWidgets = FastList.newInstance();
         for (Element subElement: subElementList) {
-            if ("section".equals(subElement.getNodeName())) {
-                subWidgets.add(new Section(modelScreen, subElement));
-            } else if ("container".equals(subElement.getNodeName())) {
-                subWidgets.add(new Container(modelScreen, subElement));
-            } else if ("screenlet".equals(subElement.getNodeName())) {
-                subWidgets.add(new Screenlet(modelScreen, subElement));
-            } else if ("include-screen".equals(subElement.getNodeName())) {
-                subWidgets.add(new IncludeScreen(modelScreen, subElement));
-            } else if ("decorator-screen".equals(subElement.getNodeName())) {
-                subWidgets.add(new DecoratorScreen(modelScreen, subElement));
-            } else if ("decorator-section-include".equals(subElement.getNodeName())) {
-                subWidgets.add(new DecoratorSectionInclude(modelScreen, subElement));
-            } else if ("label".equals(subElement.getNodeName())) {
-                subWidgets.add(new Label(modelScreen, subElement));
-            } else if ("include-form".equals(subElement.getNodeName())) {
-                subWidgets.add(new Form(modelScreen, subElement));
-            } else if ("include-menu".equals(subElement.getNodeName())) {
-                subWidgets.add(new Menu(modelScreen, subElement));
-            } else if ("include-tree".equals(subElement.getNodeName())) {
-                subWidgets.add(new Tree(modelScreen, subElement));
-            } else if ("content".equals(subElement.getNodeName())) {
-                subWidgets.add(new Content(modelScreen, subElement));
-            } else if ("sub-content".equals(subElement.getNodeName())) {
-                subWidgets.add(new SubContent(modelScreen, subElement));
-            } else if ("platform-specific".equals(subElement.getNodeName())) {
-                subWidgets.add(new PlatformSpecific(modelScreen, subElement));
-            } else if ("link".equals(subElement.getNodeName())) {
-                subWidgets.add(new Link(modelScreen, subElement));
-            } else if ("image".equals(subElement.getNodeName())) {
-                subWidgets.add(new Image(modelScreen, subElement));
-            } else if ("iterate-section".equals(subElement.getNodeName())) {
-                subWidgets.add(new IterateSectionWidget(modelScreen, subElement));
-            } else if ("horizontal-separator".equals(subElement.getNodeName())) {
-                subWidgets.add(new HorizontalSeparator(modelScreen, subElement));
-            } else {
-                throw new IllegalArgumentException("Found invalid screen widget element with name: " + subElement.getNodeName());
-            }
+            subWidgets.add(WidgetFactory.getModelScreenWidget(modelScreen, subElement));
         }
-
         return subWidgets;
     }
 
@@ -170,6 +134,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Section extends ModelScreenWidget {
+        public static final String TAG_NAME = "section";
         protected ModelScreenCondition condition;
         protected List<ModelScreenAction> actions;
         protected List<ModelScreenWidget> subWidgets;
@@ -266,6 +231,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Container extends ModelScreenWidget {
+        public static final String TAG_NAME = "container";
         protected FlexibleStringExpander idExdr;
         protected FlexibleStringExpander styleExdr;
         protected FlexibleStringExpander autoUpdateTargetExdr;
@@ -325,6 +291,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Screenlet extends ModelScreenWidget {
+        public static final String TAG_NAME = "screenlet";
         protected FlexibleStringExpander idExdr;
         protected FlexibleStringExpander titleExdr;
         protected Menu navigationMenu = null;
@@ -471,6 +438,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class HorizontalSeparator extends ModelScreenWidget {
+        public static final String TAG_NAME = "horizontal-separator";
         protected FlexibleStringExpander idExdr;
         protected FlexibleStringExpander styleExdr;
 
@@ -500,6 +468,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class IncludeScreen extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-screen";
         protected FlexibleStringExpander nameExdr;
         protected FlexibleStringExpander locationExdr;
         protected FlexibleStringExpander shareScopeExdr;
@@ -600,6 +569,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class DecoratorScreen extends ModelScreenWidget {
+        public static final String TAG_NAME = "decorator-screen";
         protected FlexibleStringExpander nameExdr;
         protected FlexibleStringExpander locationExdr;
         protected Map<String, DecoratorSection> sectionMap = new HashMap<String, DecoratorSection>();
@@ -688,6 +658,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class DecoratorSection extends ModelScreenWidget {
+        public static final String TAG_NAME = "decorator-section";
         protected List<ModelScreenWidget> subWidgets;
 
         public DecoratorSection(ModelScreen modelScreen, Element decoratorSectionElement) {
@@ -710,6 +681,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class DecoratorSectionInclude extends ModelScreenWidget {
+        public static final String TAG_NAME = "decorator-section-include";
 
         public DecoratorSectionInclude(ModelScreen modelScreen, Element decoratorSectionElement) {
             super(modelScreen, decoratorSectionElement);
@@ -744,6 +716,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Label extends ModelScreenWidget {
+        public static final String TAG_NAME = "label";
         protected FlexibleStringExpander textExdr;
 
         protected FlexibleStringExpander idExdr;
@@ -796,6 +769,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Form extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-form";
         protected FlexibleStringExpander nameExdr;
         protected FlexibleStringExpander locationExdr;
         protected FlexibleStringExpander shareScopeExdr;
@@ -884,6 +858,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Tree extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-tree";
         protected FlexibleStringExpander nameExdr;
         protected FlexibleStringExpander locationExdr;
         protected FlexibleStringExpander shareScopeExdr;
@@ -966,6 +941,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class PlatformSpecific extends ModelScreenWidget {
+        public static final String TAG_NAME = "platform-specific";
         protected Map<String, ModelScreenWidget> subWidgets;
 
         public PlatformSpecific(ModelScreen modelScreen, Element platformSpecificElement) {
@@ -1013,6 +989,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Content extends ModelScreenWidget {
+        public static final String TAG_NAME = "content";
 
         protected FlexibleStringExpander contentId;
         protected FlexibleStringExpander editRequest;
@@ -1239,6 +1216,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class SubContent extends ModelScreenWidget {
+        public static final String TAG_NAME = "sub-content";
         protected FlexibleStringExpander contentId;
         protected FlexibleStringExpander mapKey;
         protected FlexibleStringExpander editRequest;
@@ -1306,6 +1284,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Menu extends ModelScreenWidget {
+        public static final String TAG_NAME = "include-menu";
         protected FlexibleStringExpander nameExdr;
         protected FlexibleStringExpander locationExdr;
 
@@ -1366,6 +1345,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Link extends ModelScreenWidget {
+        public static final String TAG_NAME = "link";
         protected FlexibleStringExpander textExdr;
         protected FlexibleStringExpander idExdr;
         protected FlexibleStringExpander styleExdr;
@@ -1559,6 +1539,7 @@ public abstract class ModelScreenWidget 
     }
 
     public static class Image extends ModelScreenWidget {
+        public static final String TAG_NAME = "image";
         protected FlexibleStringExpander srcExdr;
         protected FlexibleStringExpander idExdr;
         protected FlexibleStringExpander styleExdr;