001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.service;
019:
020: import java.io.IOException;
021: import java.io.Serializable;
022: import java.net.URL;
023: import java.util.Collection;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Set;
028:
029: import javax.xml.parsers.ParserConfigurationException;
030:
031: import javolution.util.FastList;
032: import javolution.util.FastMap;
033:
034: import org.apache.commons.collections.map.LinkedMap;
035: import org.ofbiz.base.config.GenericConfigException;
036: import org.ofbiz.base.config.ResourceHandler;
037: import org.ofbiz.base.util.Debug;
038: import org.ofbiz.base.util.GeneralException;
039: import org.ofbiz.base.util.UtilTimer;
040: import org.ofbiz.base.util.UtilValidate;
041: import org.ofbiz.base.util.UtilXml;
042: import org.ofbiz.entity.GenericDelegator;
043: import org.ofbiz.entity.GenericEntityException;
044: import org.ofbiz.entity.model.ModelEntity;
045: import org.ofbiz.entity.model.ModelField;
046: import org.ofbiz.entity.model.ModelFieldType;
047: import org.ofbiz.service.group.GroupModel;
048: import org.w3c.dom.Document;
049: import org.w3c.dom.Element;
050: import org.w3c.dom.Node;
051: import org.w3c.dom.NodeList;
052: import org.xml.sax.SAXException;
053:
054: /**
055: * Generic Service - Service Definition Reader
056: */
057:
058: public class ModelServiceReader implements Serializable {
059:
060: public static final String module = ModelServiceReader.class
061: .getName();
062:
063: /** is either from a URL or from a ResourceLoader (through the ResourceHandler) */
064: protected boolean isFromURL;
065: protected URL readerURL = null;
066: protected ResourceHandler handler = null;
067: protected Map modelServices = null;
068: protected DispatchContext dctx = null;
069:
070: public static Map getModelServiceMap(URL readerURL,
071: DispatchContext dctx) {
072: if (readerURL == null) {
073: Debug.logError("Cannot add reader with a null reader URL",
074: module);
075: return null;
076: }
077:
078: ModelServiceReader reader = new ModelServiceReader(readerURL,
079: dctx);
080: return reader.getModelServices();
081: }
082:
083: public static Map getModelServiceMap(ResourceHandler handler,
084: DispatchContext dctx) {
085: ModelServiceReader reader = new ModelServiceReader(handler,
086: dctx);
087: return reader.getModelServices();
088: }
089:
090: protected ModelServiceReader(URL readerURL, DispatchContext dctx) {
091: this .isFromURL = true;
092: this .readerURL = readerURL;
093: this .handler = null;
094: this .dctx = dctx;
095: // preload models...
096: getModelServices();
097: }
098:
099: protected ModelServiceReader(ResourceHandler handler,
100: DispatchContext dctx) {
101: this .isFromURL = false;
102: this .readerURL = null;
103: this .handler = handler;
104: this .dctx = dctx;
105: // preload models...
106: getModelServices();
107: }
108:
109: public Map getModelServices() {
110: if (modelServices == null) { // don't want to block here
111: synchronized (ModelServiceReader.class) {
112: // must check if null again as one of the blocked threads can still enter
113: if (modelServices == null) { // now it's safe
114: modelServices = FastMap.newInstance();
115:
116: UtilTimer utilTimer = new UtilTimer();
117:
118: Document document;
119:
120: if (this .isFromURL) {
121: // utilTimer.timerString("Before getDocument in file " + readerURL);
122: document = getDocument(readerURL);
123:
124: if (document == null) {
125: modelServices = null;
126: return null;
127: }
128: } else {
129: // utilTimer.timerString("Before getDocument in " + handler);
130: try {
131: document = handler.getDocument();
132: } catch (GenericConfigException e) {
133: Debug
134: .logError(
135: e,
136: "Error getting XML document from resource",
137: module);
138: return null;
139: }
140: }
141:
142: if (this .isFromURL) {// utilTimer.timerString("Before getDocumentElement in file " + readerURL);
143: } else {// utilTimer.timerString("Before getDocumentElement in " + handler);
144: }
145:
146: Element docElement = document.getDocumentElement();
147: if (docElement == null) {
148: modelServices = null;
149: return null;
150: }
151:
152: docElement.normalize();
153:
154: int i = 0;
155: Node curChild = docElement.getFirstChild();
156: if (curChild != null) {
157: if (this .isFromURL) {
158: utilTimer
159: .timerString("Before start of service loop in file "
160: + readerURL);
161: } else {
162: utilTimer
163: .timerString("Before start of service loop in "
164: + handler);
165: }
166:
167: do {
168: if (curChild.getNodeType() == Node.ELEMENT_NODE
169: && "service".equals(curChild
170: .getNodeName())) {
171: i++;
172: Element curService = (Element) curChild;
173: String serviceName = UtilXml
174: .checkEmpty(curService
175: .getAttribute("name"));
176:
177: // check to see if service with same name has already been read
178: if (modelServices
179: .containsKey(serviceName)) {
180: Debug
181: .logWarning(
182: "WARNING: Service "
183: + serviceName
184: + " is defined more than once, "
185: + "most recent will over-write previous definition(s)",
186: module);
187: }
188:
189: // utilTimer.timerString(" After serviceName -- " + i + " --");
190: ModelService service = createModelService(curService);
191:
192: // utilTimer.timerString(" After createModelService -- " + i + " --");
193: if (service != null) {
194: modelServices.put(serviceName,
195: service);
196: // utilTimer.timerString(" After modelServices.put -- " + i + " --");
197: /*
198: int reqIn = service.getParameterNames(ModelService.IN_PARAM, false).size();
199: int optIn = service.getParameterNames(ModelService.IN_PARAM, true).size() - reqIn;
200: int reqOut = service.getParameterNames(ModelService.OUT_PARAM, false).size();
201: int optOut = service.getParameterNames(ModelService.OUT_PARAM, true).size() - reqOut;
202:
203: if (Debug.verboseOn()) {
204: String msg = "-- getModelService: # " + i + " Loaded service: " + serviceName +
205: " (IN) " + reqIn + "/" + optIn + " (OUT) " + reqOut + "/" + optOut;
206:
207: Debug.logVerbose(msg, module);
208: }
209: */
210: } else {
211: Debug
212: .logWarning(
213: "-- -- SERVICE ERROR:getModelService: Could not create service for serviceName: "
214: + serviceName,
215: module);
216: }
217:
218: }
219: } while ((curChild = curChild.getNextSibling()) != null);
220: } else {
221: Debug.logWarning("No child nodes found.",
222: module);
223: }
224: if (this .isFromURL) {
225: utilTimer.timerString("Finished file "
226: + readerURL + " - Total Services: " + i
227: + " FINISHED");
228: Debug.logImportant("Loaded " + i
229: + " Service definitions from "
230: + readerURL, module);
231: } else {
232: utilTimer.timerString("Finished document in "
233: + handler + " - Total Services: " + i
234: + " FINISHED");
235: if (Debug.importantOn()) {
236: String resourceLocation = handler
237: .getLocation();
238: try {
239: resourceLocation = handler.getURL()
240: .toExternalForm();
241: } catch (GenericConfigException e) {
242: Debug.logError(e,
243: "Could not get resource URL",
244: module);
245: }
246: Debug.logImportant("Loaded " + i
247: + " Service definitions from "
248: + resourceLocation, module);
249: }
250: }
251: }
252: }
253: }
254: return modelServices;
255: }
256:
257: /**
258: * Gets an Service object based on a definition from the specified XML Service descriptor file.
259: * @param serviceName The serviceName of the Service definition to use.
260: * @return An Service object describing the specified service of the specified descriptor file.
261: */
262: public ModelService getModelService(String serviceName) {
263: Map ec = getModelServices();
264:
265: if (ec != null)
266: return (ModelService) ec.get(serviceName);
267: else
268: return null;
269: }
270:
271: /**
272: * Creates a Iterator with the serviceName of each Service defined in the specified XML Service Descriptor file.
273: * @return A Iterator of serviceName Strings
274: */
275: public Iterator getServiceNamesIterator() {
276: Collection collection = getServiceNames();
277:
278: if (collection != null) {
279: return collection.iterator();
280: } else {
281: return null;
282: }
283: }
284:
285: /**
286: * Creates a Collection with the serviceName of each Service defined in the specified XML Service Descriptor file.
287: * @return A Collection of serviceName Strings
288: */
289: public Collection getServiceNames() {
290: Map ec = getModelServices();
291:
292: return ec.keySet();
293: }
294:
295: protected ModelService createModelService(Element serviceElement) {
296: ModelService service = new ModelService();
297:
298: service.name = UtilXml.checkEmpty(serviceElement
299: .getAttribute("name"));
300: service.engineName = UtilXml.checkEmpty(serviceElement
301: .getAttribute("engine"));
302: service.location = UtilXml.checkEmpty(serviceElement
303: .getAttribute("location"));
304: service.invoke = UtilXml.checkEmpty(serviceElement
305: .getAttribute("invoke"));
306: service.defaultEntityName = UtilXml.checkEmpty(serviceElement
307: .getAttribute("default-entity-name"));
308: service.fromLoader = isFromURL ? readerURL.toExternalForm()
309: : handler.getLoaderName();
310:
311: // these default to true; if anything but true, make false
312: service.auth = "true".equalsIgnoreCase(serviceElement
313: .getAttribute("auth"));
314: service.export = "true".equalsIgnoreCase(serviceElement
315: .getAttribute("export"));
316: service.debug = "true".equalsIgnoreCase(serviceElement
317: .getAttribute("debug"));
318:
319: // this defaults to true; if anything but false, make it true
320: service.validate = !"false".equalsIgnoreCase(serviceElement
321: .getAttribute("validate"));
322: service.useTransaction = !"false"
323: .equalsIgnoreCase(serviceElement
324: .getAttribute("use-transaction"));
325: service.requireNewTransaction = !"false"
326: .equalsIgnoreCase(serviceElement
327: .getAttribute("require-new-transaction"));
328:
329: // set the max retry field
330: String maxRetryStr = UtilXml.checkEmpty(serviceElement
331: .getAttribute("max-retry"));
332: int maxRetry = -1;
333: if (!UtilValidate.isEmpty(maxRetryStr)) {
334: try {
335: maxRetry = Integer.parseInt(maxRetryStr);
336: } catch (NumberFormatException e) {
337: Debug.logWarning(e, "Setting maxRetry to -1 (default)",
338: module);
339: maxRetry = -1;
340: }
341: }
342: service.maxRetry = maxRetry;
343:
344: // get the timeout and convert to int
345: String timeoutStr = UtilXml.checkEmpty(serviceElement
346: .getAttribute("transaction-timeout"), serviceElement
347: .getAttribute("transaction-timout"));
348: int timeout = 0;
349: if (!UtilValidate.isEmpty(timeoutStr)) {
350: try {
351: timeout = Integer.parseInt(timeoutStr);
352: } catch (NumberFormatException e) {
353: Debug.logWarning(e, "Setting timeout to 0 (default)",
354: module);
355: timeout = 0;
356: }
357: }
358: service.transactionTimeout = timeout;
359:
360: service.description = getCDATADef(serviceElement, "description");
361: service.nameSpace = getCDATADef(serviceElement, "namespace");
362:
363: // contruct the context
364: service.contextInfo = FastMap.newInstance();
365: this .createNotification(serviceElement, service);
366: this .createPermission(serviceElement, service);
367: this .createPermGroups(serviceElement, service);
368: this .createGroupDefs(serviceElement, service);
369: this .createImplDefs(serviceElement, service);
370: this .createAutoAttrDefs(serviceElement, service);
371: this .createAttrDefs(serviceElement, service);
372: this .createOverrideDefs(serviceElement, service);
373:
374: return service;
375: }
376:
377: protected String getCDATADef(Element baseElement, String tagName) {
378: String value = "";
379: NodeList nl = baseElement.getElementsByTagName(tagName);
380:
381: // if there are more then one decriptions we will use only the first one
382: if (nl.getLength() > 0) {
383: Node n = nl.item(0);
384: NodeList childNodes = n.getChildNodes();
385:
386: if (childNodes.getLength() > 0) {
387: Node cdata = childNodes.item(0);
388:
389: value = UtilXml.checkEmpty(cdata.getNodeValue());
390: }
391: }
392: return value;
393: }
394:
395: protected void createNotification(Element baseElement,
396: ModelService model) {
397: List n = UtilXml.childElementList(baseElement, "notification");
398: // default notification groups
399: ModelNotification nSuccess = new ModelNotification();
400: nSuccess.notificationEvent = "success";
401: nSuccess.notificationGroupName = "default.success."
402: + model.fromLoader;
403: model.notifications.add(nSuccess);
404:
405: ModelNotification nFail = new ModelNotification();
406: nFail.notificationEvent = "fail";
407: nFail.notificationGroupName = "default.fail."
408: + model.fromLoader;
409: model.notifications.add(nFail);
410:
411: ModelNotification nError = new ModelNotification();
412: nError.notificationEvent = "error";
413: nError.notificationGroupName = "default.error."
414: + model.fromLoader;
415: model.notifications.add(nError);
416:
417: if (n != null) {
418: Iterator i = n.iterator();
419: while (i.hasNext()) {
420: Element e = (Element) i.next();
421: ModelNotification notify = new ModelNotification();
422: notify.notificationEvent = e.getAttribute("event");
423: notify.notificationGroupName = e.getAttribute("group");
424: model.notifications.add(notify);
425: }
426: }
427: }
428:
429: protected void createPermission(Element baseElement,
430: ModelService model) {
431: Element e = UtilXml.firstChildElement(baseElement,
432: "permission-service");
433: if (e != null) {
434: model.permissionServiceName = e
435: .getAttribute("service-name");
436: model.permissionMainAction = e.getAttribute("main-action");
437: model.permissionResourceDesc = e
438: .getAttribute("resource-description");
439: model.auth = true; // auth is always required when permissions are set
440: }
441: }
442:
443: protected void createPermGroups(Element baseElement,
444: ModelService model) {
445: List permGroups = UtilXml.childElementList(baseElement,
446: "required-permissions");
447: Iterator permIter = permGroups.iterator();
448:
449: while (permIter.hasNext()) {
450: Element element = (Element) permIter.next();
451: ModelPermGroup group = new ModelPermGroup();
452: group.joinType = element.getAttribute("join-type");
453: createGroupPermissions(element, group, model);
454: model.permissionGroups.add(group);
455: }
456: }
457:
458: protected void createGroupPermissions(Element baseElement,
459: ModelPermGroup group, ModelService service) {
460: List permElements = UtilXml.childElementList(baseElement,
461: "check-permission");
462: List rolePermElements = UtilXml.childElementList(baseElement,
463: "check-role-member");
464:
465: // create the simple permissions
466: Iterator si = permElements.iterator();
467: while (si.hasNext()) {
468: Element element = (Element) si.next();
469: ModelPermission perm = new ModelPermission();
470: perm.nameOrRole = element.getAttribute("permission");
471: perm.action = element.getAttribute("action");
472: if (perm.action != null && perm.action.length() > 0) {
473: perm.permissionType = ModelPermission.ENTITY_PERMISSION;
474: } else {
475: perm.permissionType = ModelPermission.PERMISSION;
476: }
477: perm.serviceModel = service;
478: group.permissions.add(perm);
479: }
480:
481: // create the role member permissions
482: Iterator ri = rolePermElements.iterator();
483: while (ri.hasNext()) {
484: Element element = (Element) ri.next();
485: ModelPermission perm = new ModelPermission();
486: perm.permissionType = ModelPermission.ROLE_MEMBER;
487: perm.nameOrRole = element.getAttribute("role-type");
488: perm.serviceModel = service;
489: group.permissions.add(perm);
490: }
491: }
492:
493: protected void createGroupDefs(Element baseElement,
494: ModelService service) {
495: List group = UtilXml.childElementList(baseElement, "group");
496: if (group != null && group.size() > 0) {
497: Element groupElement = (Element) group.get(0);
498: groupElement.setAttribute("name", "_" + service.name
499: + ".group");
500: service.internalGroup = new GroupModel(groupElement);
501: service.invoke = service.internalGroup.getGroupName();
502: Debug.logWarning("Created INTERNAL GROUP model ["
503: + service.internalGroup + "]", module);
504: }
505: }
506:
507: protected void createImplDefs(Element baseElement,
508: ModelService service) {
509: List implElements = UtilXml.childElementList(baseElement,
510: "implements");
511: Iterator implIter = implElements.iterator();
512:
513: while (implIter.hasNext()) {
514: Element implement = (Element) implIter.next();
515: String serviceName = UtilXml.checkEmpty(implement
516: .getAttribute("service"));
517: boolean optional = UtilXml.checkBoolean(implement
518: .getAttribute("optional"), false);
519: if (serviceName.length() > 0)
520: service.implServices.add(new ModelServiceIface(
521: serviceName, optional));
522: //service.implServices.add(serviceName);
523: }
524: }
525:
526: protected void createAutoAttrDefs(Element baseElement,
527: ModelService service) {
528: List autoElement = UtilXml.childElementList(baseElement,
529: "auto-attributes");
530: Iterator autoIter = autoElement.iterator();
531:
532: while (autoIter.hasNext()) {
533: Element element = (Element) autoIter.next();
534: createAutoAttrDef(element, service);
535: }
536: }
537:
538: protected void createAutoAttrDef(Element autoElement,
539: ModelService service) {
540: // get the entity name; first from the auto-attributes then from the service def
541: String entityName = UtilXml.checkEmpty(autoElement
542: .getAttribute("entity-name"));
543: if (entityName == null || entityName.length() == 0) {
544: entityName = service.defaultEntityName;
545: if (entityName == null || entityName.length() == 0) {
546: Debug
547: .logWarning(
548: "Auto-Attribute does not specify an entity-name; not default-entity on service definition",
549: module);
550: }
551: }
552:
553: // get the include type 'pk|nonpk|all'
554: String includeType = UtilXml.checkEmpty(autoElement
555: .getAttribute("include"));
556: boolean includePk = "pk".equals(includeType)
557: || "all".equals(includeType);
558: boolean includeNonPk = "nonpk".equals(includeType)
559: || "all".equals(includeType);
560:
561: // need a delegator for this
562: GenericDelegator delegator = dctx.getDelegator();
563: if (delegator == null) {
564: Debug
565: .logWarning(
566: "Cannot use auto-attribute fields with a null delegator",
567: module);
568: }
569:
570: if (delegator != null && entityName != null) {
571: Map modelParamMap = new LinkedMap();
572: try {
573: ModelEntity entity = delegator
574: .getModelEntity(entityName);
575: if (entity == null) {
576: throw new GeneralException(
577: "Could not find entity with name ["
578: + entityName + "]");
579: }
580: Iterator fieldsIter = entity.getFieldsIterator();
581: if (fieldsIter != null) {
582: while (fieldsIter.hasNext()) {
583: ModelField field = (ModelField) fieldsIter
584: .next();
585: if ((!field.getIsAutoCreatedInternal())
586: && ((field.getIsPk() && includePk) || (!field
587: .getIsPk() && includeNonPk))) {
588: ModelFieldType fieldType = delegator
589: .getEntityFieldType(entity, field
590: .getType());
591: if (fieldType == null) {
592: throw new GeneralException(
593: "Null field type from delegator for entity ["
594: + entityName + "]");
595: }
596: ModelParam param = new ModelParam();
597: param.entityName = entityName;
598: param.fieldName = field.getName();
599: param.name = field.getName();
600: param.type = fieldType.getJavaType();
601: param.mode = UtilXml.checkEmpty(autoElement
602: .getAttribute("mode"));
603: param.optional = "true"
604: .equalsIgnoreCase(autoElement
605: .getAttribute("optional")); // default to true
606: param.formDisplay = !"false"
607: .equalsIgnoreCase(autoElement
608: .getAttribute("form-display")); // default to false
609: modelParamMap.put(field.getName(), param);
610: }
611: }
612:
613: // get the excludes list; and remove those from the map
614: List excludes = UtilXml.childElementList(
615: autoElement, "exclude");
616: if (excludes != null) {
617: Iterator excludesIter = excludes.iterator();
618: while (excludesIter.hasNext()) {
619: Element exclude = (Element) excludesIter
620: .next();
621: modelParamMap
622: .remove(UtilXml
623: .checkEmpty(exclude
624: .getAttribute("field-name")));
625: }
626: }
627:
628: // now add in all the remaining params
629: Set keySet = modelParamMap.keySet();
630: Iterator setIter = keySet.iterator();
631: while (setIter.hasNext()) {
632: ModelParam this Param = (ModelParam) modelParamMap
633: .get(setIter.next());
634: //Debug.logInfo("Adding Param to " + service.name + ": " + thisParam.name + " [" + thisParam.mode + "] " + thisParam.type + " (" + thisParam.optional + ")", module);
635: service.addParam(this Param);
636: }
637: }
638: } catch (GenericEntityException e) {
639: Debug.logError(e, "Problem loading auto-attributes ["
640: + entityName + "] for " + service.name, module);
641: } catch (GeneralException e) {
642: Debug.logError(e, "Cannot load auto-attributes : "
643: + e.getMessage() + " for " + service.name,
644: module);
645: }
646: }
647: }
648:
649: protected void createAttrDefs(Element baseElement,
650: ModelService service) {
651: // Add in the defined attributes (override the above defaults if specified)
652: List paramElements = UtilXml.childElementList(baseElement,
653: "attribute");
654: Iterator paramIter = paramElements.iterator();
655:
656: while (paramIter.hasNext()) {
657: Element attribute = (Element) paramIter.next();
658: ModelParam param = new ModelParam();
659:
660: param.name = UtilXml.checkEmpty(attribute
661: .getAttribute("name"));
662: param.type = UtilXml.checkEmpty(attribute
663: .getAttribute("type"));
664: param.mode = UtilXml.checkEmpty(attribute
665: .getAttribute("mode"));
666: param.entityName = UtilXml.checkEmpty(attribute
667: .getAttribute("entity-name"));
668: param.fieldName = UtilXml.checkEmpty(attribute
669: .getAttribute("field-name"));
670: param.stringMapPrefix = UtilXml.checkEmpty(attribute
671: .getAttribute("string-map-prefix"));
672: param.stringListSuffix = UtilXml.checkEmpty(attribute
673: .getAttribute("string-list-suffix"));
674: param.formLabel = attribute.hasAttribute("form-label") ? attribute
675: .getAttribute("form-label")
676: : null;
677: param.optional = "true".equalsIgnoreCase(attribute
678: .getAttribute("optional")); // default to true
679: param.formDisplay = !"false".equalsIgnoreCase(attribute
680: .getAttribute("form-display")); // default to false
681:
682: // default value
683: String defValue = attribute.getAttribute("default-value");
684: if (UtilValidate.isNotEmpty(defValue)) {
685: Debug.logInfo("Got a default-value [" + defValue
686: + "] for service attribute [" + service.name
687: + "." + param.name + "]", module);
688: param.setDefaultValue(defValue);
689: }
690:
691: // set the entity name to the default if not specified
692: if (param.entityName.length() == 0) {
693: param.entityName = service.defaultEntityName;
694: }
695:
696: // set the field-name to the name if entity name is specified but no field-name
697: if (param.fieldName.length() == 0
698: && param.entityName.length() > 0) {
699: param.fieldName = param.name;
700: }
701:
702: // set the validators
703: this .addValidators(attribute, param);
704: service.addParam(param);
705: }
706:
707: // Add the default optional parameters
708: ModelParam def;
709:
710: // responseMessage
711: def = new ModelParam();
712: def.name = ModelService.RESPONSE_MESSAGE;
713: def.type = "String";
714: def.mode = "OUT";
715: def.optional = true;
716: def.internal = true;
717: service.addParam(def);
718: // errorMessage
719: def = new ModelParam();
720: def.name = ModelService.ERROR_MESSAGE;
721: def.type = "String";
722: def.mode = "OUT";
723: def.optional = true;
724: def.internal = true;
725: service.addParam(def);
726: // errorMessageList
727: def = new ModelParam();
728: def.name = ModelService.ERROR_MESSAGE_LIST;
729: def.type = "java.util.List";
730: def.mode = "OUT";
731: def.optional = true;
732: def.internal = true;
733: service.addParam(def);
734: // successMessage
735: def = new ModelParam();
736: def.name = ModelService.SUCCESS_MESSAGE;
737: def.type = "String";
738: def.mode = "OUT";
739: def.optional = true;
740: def.internal = true;
741: service.addParam(def);
742: // successMessageList
743: def = new ModelParam();
744: def.name = ModelService.SUCCESS_MESSAGE_LIST;
745: def.type = "java.util.List";
746: def.mode = "OUT";
747: def.optional = true;
748: def.internal = true;
749: service.addParam(def);
750: // userLogin
751: def = new ModelParam();
752: def.name = "userLogin";
753: def.type = "org.ofbiz.entity.GenericValue";
754: def.mode = "INOUT";
755: def.optional = true;
756: def.internal = true;
757: service.addParam(def);
758: // Locale
759: def = new ModelParam();
760: def.name = "locale";
761: def.type = "java.util.Locale";
762: def.mode = "INOUT";
763: def.optional = true;
764: def.internal = true;
765: service.addParam(def);
766: }
767:
768: protected void createOverrideDefs(Element baseElement,
769: ModelService service) {
770: List paramElements = UtilXml.childElementList(baseElement,
771: "override");
772: Iterator paramIter = paramElements.iterator();
773:
774: while (paramIter.hasNext()) {
775: Element attribute = (Element) paramIter.next();
776: String name = UtilXml.checkEmpty(attribute
777: .getAttribute("name"));
778: ModelParam param = service.getParam(name);
779: boolean directToParams = true;
780: if (param == null) {
781: if (!service.inheritedParameters
782: && (service.implServices.size() > 0 || "group"
783: .equals(service.engineName))) {
784: // create a temp def to place in the ModelService
785: // this will get read when we read implemented services
786: directToParams = false;
787: param = new ModelParam();
788: param.name = name;
789: } else {
790: Debug.logWarning(
791: "No parameter found for override parameter named: "
792: + name + " in service "
793: + service.name, module);
794: }
795: }
796:
797: if (param != null) {
798: // set only modified values
799: if (attribute.getAttribute("type") != null
800: && attribute.getAttribute("type").length() > 0) {
801: param.type = UtilXml.checkEmpty(attribute
802: .getAttribute("type"));
803: }
804: if (attribute.getAttribute("mode") != null
805: && attribute.getAttribute("mode").length() > 0) {
806: param.mode = UtilXml.checkEmpty(attribute
807: .getAttribute("mode"));
808: }
809: if (attribute.getAttribute("entity-name") != null
810: && attribute.getAttribute("entity-name")
811: .length() > 0) {
812: param.entityName = UtilXml.checkEmpty(attribute
813: .getAttribute("entity-name"));
814: }
815: if (attribute.getAttribute("field-name") != null
816: && attribute.getAttribute("field-name")
817: .length() > 0) {
818: param.fieldName = UtilXml.checkEmpty(attribute
819: .getAttribute("field-name"));
820: }
821: if (attribute.getAttribute("form-label") != null
822: && attribute.getAttribute("form-label")
823: .length() > 0) {
824: param.formLabel = UtilXml.checkEmpty(attribute
825: .getAttribute("form-label"));
826: }
827: if (attribute.getAttribute("optional") != null
828: && attribute.getAttribute("optional").length() > 0) {
829: param.optional = "true".equalsIgnoreCase(attribute
830: .getAttribute("optional")); // default to true
831: param.overrideOptional = true;
832: }
833: if (attribute.getAttribute("form-display") != null
834: && attribute.getAttribute("form-display")
835: .length() > 0) {
836: param.formDisplay = !"false"
837: .equalsIgnoreCase(attribute
838: .getAttribute("form-display")); // default to false
839: param.overrideFormDisplay = true;
840: }
841:
842: // default value
843: String defValue = attribute
844: .getAttribute("default-value");
845: if (UtilValidate.isNotEmpty(defValue)) {
846: param.setDefaultValue(defValue);
847: }
848:
849: // override validators
850: this .addValidators(attribute, param);
851:
852: if (directToParams) {
853: service.addParam(param);
854: } else {
855: service.overrideParameters.add(param);
856: }
857: }
858: }
859: }
860:
861: protected void addValidators(Element attribute, ModelParam param) {
862: List validateElements = UtilXml.childElementList(attribute,
863: "type-validate");
864: if (validateElements != null && validateElements.size() > 0) {
865: // always clear out old ones; never append
866: param.validators = FastList.newInstance();
867:
868: Iterator i = validateElements.iterator();
869: Element validate = (Element) i.next();
870: String methodName = validate.getAttribute("method");
871: String className = validate.getAttribute("class");
872:
873: Element fail = UtilXml.firstChildElement(validate,
874: "fail-message");
875: if (fail != null) {
876: String message = fail.getAttribute("message");
877: param.addValidator(className, methodName, message);
878: } else {
879: fail = UtilXml.firstChildElement(validate,
880: "fail-property");
881: if (fail != null) {
882: String resource = fail.getAttribute("resource");
883: String property = fail.getAttribute("property");
884: param.addValidator(className, methodName, resource,
885: property);
886: }
887: }
888: }
889: }
890:
891: protected Document getDocument(URL url) {
892: if (url == null)
893: return null;
894: Document document = null;
895:
896: try {
897: document = UtilXml.readXmlDocument(url, true);
898: } catch (SAXException sxe) {
899: // Error generated during parsing)
900: Exception x = sxe;
901:
902: if (sxe.getException() != null)
903: x = sxe.getException();
904: x.printStackTrace();
905: } catch (ParserConfigurationException pce) {
906: // Parser with specified options can't be built
907: pce.printStackTrace();
908: } catch (IOException ioe) {
909: ioe.printStackTrace();
910: }
911:
912: return document;
913: }
914: }
|