1 16 package org.apache.cocoon.forms.formmodel; 17 18 import java.util.ArrayList ; 19 import java.util.Collections ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 import java.util.Map ; 24 25 import org.apache.avalon.framework.CascadingException; 26 import org.apache.avalon.framework.activity.Disposable; 27 import org.apache.avalon.framework.service.ServiceException; 28 import org.apache.avalon.framework.service.ServiceManager; 29 import org.apache.avalon.framework.service.ServiceSelector; 30 import org.apache.avalon.framework.service.Serviceable; 31 import org.apache.cocoon.forms.FormsConstants; 32 import org.apache.cocoon.forms.datatype.DatatypeManager; 33 import org.apache.cocoon.forms.event.CreateListener; 34 import org.apache.cocoon.forms.event.WidgetListener; 35 import org.apache.cocoon.forms.event.WidgetListenerBuilder; 36 import org.apache.cocoon.forms.expression.ExpressionManager; 37 import org.apache.cocoon.forms.util.DomHelper; 38 import org.apache.cocoon.forms.validation.WidgetValidatorBuilder; 39 import org.apache.excalibur.xml.sax.XMLizable; 40 import org.w3c.dom.Element ; 41 import org.w3c.dom.Node ; 42 import org.w3c.dom.NodeList ; 43 44 50 public abstract class AbstractWidgetDefinitionBuilder implements WidgetDefinitionBuilder, Serviceable, Disposable { 51 protected ServiceSelector widgetDefinitionBuilderSelector; 52 protected ServiceSelector widgetValidatorBuilderSelector; 53 protected ServiceSelector widgetListenerBuilderSelector; 54 protected DatatypeManager datatypeManager; 55 protected ExpressionManager expressionManager; 56 protected ServiceManager serviceManager; 57 58 protected WidgetDefinitionBuilderContext context = null; 59 60 public WidgetDefinition buildWidgetDefinition(Element widgetElement, WidgetDefinitionBuilderContext context) throws Exception { 61 this.context = new WidgetDefinitionBuilderContext(context); 63 64 65 WidgetDefinition def = buildWidgetDefinition(widgetElement); 66 67 if(DomHelper.getAttributeAsBoolean(widgetElement,"register",false) && this.context!=null && this.context.getLocalLibrary()!=null) { 69 this.context.getLocalLibrary().addDefinition(def); 70 } 71 72 this.context = null; 73 return def; 74 } 75 76 public void service(ServiceManager serviceManager) throws ServiceException { 77 this.serviceManager = serviceManager; 78 this.widgetDefinitionBuilderSelector = (ServiceSelector) serviceManager.lookup(WidgetDefinitionBuilder.class.getName() + "Selector"); 79 this.datatypeManager = (DatatypeManager) serviceManager.lookup(DatatypeManager.ROLE); 80 this.expressionManager = (ExpressionManager) serviceManager.lookup(ExpressionManager.ROLE); 81 this.widgetValidatorBuilderSelector = (ServiceSelector) serviceManager.lookup(WidgetValidatorBuilder.ROLE + "Selector"); 82 this.widgetListenerBuilderSelector = (ServiceSelector) serviceManager.lookup(WidgetListenerBuilder.ROLE + "Selector"); 83 } 84 85 protected void setupDefinition(Element widgetElement, AbstractWidgetDefinition definition) throws Exception { 86 87 definition.setLocation(DomHelper.getLocationObject(widgetElement)); 89 90 91 if(this.context.getSuperDefinition()!=null) 92 definition.initializeFrom(this.context.getSuperDefinition()); 93 94 setCommonProperties(widgetElement, definition); 95 setValidators(widgetElement, definition); 96 setCreateListeners(widgetElement, definition); 97 } 98 99 private void setCommonProperties(Element widgetElement, AbstractWidgetDefinition widgetDefinition) throws Exception { 100 101 if (widgetDefinition instanceof FormDefinition) { 103 widgetDefinition.setId(DomHelper.getAttribute(widgetElement, "id", "")); 105 } else { 106 String id = DomHelper.getAttribute(widgetElement, "id"); 107 if (id.length() < 1) { 108 throw new Exception ("Missing id attribute on element '" + widgetElement.getTagName() + "' at " + 109 DomHelper.getLocation(widgetElement)); 110 } 111 if (id.indexOf('/') != -1 || id.indexOf('.') != -1) { 112 throw new Exception ("A widget name cannot contain '.' or '/' as this conflicts with widget paths, at " + 113 DomHelper.getLocation(widgetElement)); 114 } 115 if (id.indexOf(':') != -1) { 116 throw new Exception ("A widget name cannot contain ':' as this conflicts with library prefixes, at " + 117 DomHelper.getLocation(widgetElement)); 118 } 119 widgetDefinition.setId(id); 120 } 121 122 String stateValue = DomHelper.getAttribute(widgetElement, "state", null); 124 if (stateValue != null) { 125 WidgetState state = WidgetState.stateForName(stateValue); 126 if (state == null) { 127 throw new Exception ("Unknow value '" + stateValue +"' for state attribute at " + 128 DomHelper.getLocation(widgetElement)); 129 } 130 widgetDefinition.setState(state); 131 } 132 133 Element attrContainer = DomHelper.getChildElement(widgetElement, FormsConstants.DEFINITION_NS, "attributes", false); 135 if (attrContainer != null) { 136 Element [] attrs = DomHelper.getChildElements(attrContainer, FormsConstants.DEFINITION_NS, "attribute"); 138 if (attrs != null && attrs.length > 0) { 139 Map attrMap = new HashMap (); 141 for (int i = 0; i < attrs.length; i++) { 142 attrMap.put(DomHelper.getAttribute(attrs[i], "name"), DomHelper.getAttribute(attrs[i], "value")); 143 } 144 widgetDefinition.setAttributes(attrMap); 145 } 146 } 147 } 148 149 protected WidgetDefinition buildAnotherWidgetDefinition(Element widgetDefinition) throws Exception { 150 String widgetName = widgetDefinition.getLocalName(); 151 WidgetDefinitionBuilder builder = null; 152 try { 153 builder = (WidgetDefinitionBuilder)widgetDefinitionBuilderSelector.select(widgetName); 154 } catch (ServiceException e) { 155 throw new CascadingException("Unknown kind of widget '" + widgetName + "' at " + 156 DomHelper.getLocation(widgetDefinition), e); 157 } 158 159 160 return builder.buildWidgetDefinition(widgetDefinition, this.context); 161 } 162 163 protected List buildEventListeners(Element widgetElement, String elementName, Class listenerClass) throws Exception { 164 List result = null; 165 Element listenersElement = DomHelper.getChildElement(widgetElement, FormsConstants.DEFINITION_NS, elementName); 166 if (listenersElement != null) { 167 NodeList list = listenersElement.getChildNodes(); 168 for (int i = 0; i < list.getLength(); i++) { 169 if (list.item(i).getNodeType() == Node.ELEMENT_NODE) { 170 Element listenerElement = (Element )list.item(i); 171 WidgetListenerBuilder listenerBuilder = null; 172 try { 173 listenerBuilder = (WidgetListenerBuilder)widgetListenerBuilderSelector.select(listenerElement.getLocalName()); 174 } catch (ServiceException e) { 175 throw new CascadingException("Unknown kind of eventlistener '" + listenerElement.getLocalName() 176 + "' at " + DomHelper.getLocation(listenerElement), e); 177 } 178 WidgetListener listener = listenerBuilder.buildListener(listenerElement, listenerClass); 179 widgetListenerBuilderSelector.release(listenerBuilder); 180 if (result == null) result = new ArrayList (); 181 result.add(listener); 182 } 183 } 184 } 185 186 return result == null ? Collections.EMPTY_LIST : result; 187 } 188 189 protected void setDisplayData(Element widgetElement, AbstractWidgetDefinition widgetDefinition) throws Exception { 190 final String [] names = {"label", "help", "hint"}; 191 Map displayData = new HashMap (names.length); 192 for (int i = 0; i < names.length; i++) { 193 XMLizable data = null; 194 Element dataElement = DomHelper.getChildElement(widgetElement, FormsConstants.DEFINITION_NS, names[i]); 195 if (dataElement != null) { 196 data = DomHelper.compileElementContent(dataElement); 197 } 198 199 displayData.put(names[i], data); 202 } 203 204 widgetDefinition.setDisplayData(displayData); 205 } 206 207 private void setValidators(Element widgetElement, AbstractWidgetDefinition widgetDefinition) throws Exception { 208 Element validatorElement = DomHelper.getChildElement(widgetElement, FormsConstants.DEFINITION_NS, "validation"); 209 if (validatorElement != null) { 210 NodeList list = validatorElement.getChildNodes(); 211 for (int i = 0; i < list.getLength(); i++) { 212 if (list.item(i).getNodeType() == Node.ELEMENT_NODE) { 213 Element element = (Element )list.item(i); 214 String name = element.getLocalName(); 215 WidgetValidatorBuilder builder; 216 try { 217 builder = (WidgetValidatorBuilder)this.widgetValidatorBuilderSelector.select(name); 218 } catch(ServiceException e) { 219 throw new CascadingException("Unknow kind of validator '" + name + "' at " + 220 DomHelper.getLocation(element), e); 221 } 222 223 widgetDefinition.addValidator(builder.build(element, widgetDefinition)); 224 widgetValidatorBuilderSelector.release(builder); 225 } 226 } 227 } 228 } 229 230 private void setCreateListeners(Element widgetElement, AbstractWidgetDefinition widgetDefinition) throws Exception { 231 Iterator iter = buildEventListeners(widgetElement, "on-create", CreateListener.class).iterator(); 232 while (iter.hasNext()) { 233 widgetDefinition.addCreateListener((CreateListener)iter.next()); 234 } 235 } 236 237 public void dispose() { 238 this.serviceManager.release(this.widgetDefinitionBuilderSelector); 239 this.widgetDefinitionBuilderSelector = null; 240 this.serviceManager.release(this.datatypeManager); 241 this.datatypeManager = null; 242 this.serviceManager.release(this.expressionManager); 243 this.expressionManager = null; 244 this.serviceManager.release(this.widgetValidatorBuilderSelector); 245 this.widgetValidatorBuilderSelector = null; 246 this.serviceManager = null; 247 } 248 } 249 | Popular Tags |