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; |
Free forum by Nabble | Edit this page |