/*******************************************************************************
 * 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.apache.ofbiz.service;

import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.ofbiz.base.config.GenericConfigException;
import org.apache.ofbiz.base.config.ResourceHandler;
import org.apache.ofbiz.base.metrics.MetricsFactory;
import org.apache.ofbiz.base.util.Debug;
import org.apache.ofbiz.base.util.GeneralException;
import org.apache.ofbiz.base.util.UtilTimer;
import org.apache.ofbiz.base.util.UtilValidate;
import org.apache.ofbiz.base.util.UtilXml;
import org.apache.ofbiz.entity.Delegator;
import org.apache.ofbiz.entity.GenericEntityException;
import org.apache.ofbiz.entity.model.ModelEntity;
import org.apache.ofbiz.entity.model.ModelField;
import org.apache.ofbiz.entity.model.ModelFieldType;
import org.apache.ofbiz.service.ModelParam.ModelParamValidator;
import org.apache.ofbiz.service.group.GroupModel;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * Generic Service - Service Definition Reader
 */
@SuppressWarnings("serial")
public class ModelServiceReader implements Serializable {

    public static final String module = ModelServiceReader.class.getName();

    /** is either from a URL or from a ResourceLoader (through the ResourceHandler) */
    protected boolean isFromURL;
    protected URL readerURL = null;
    protected ResourceHandler handler = null;
    protected Delegator delegator = null;

    public static Map<String, ModelService> getModelServiceMap(URL readerURL, Delegator delegator) {
        if (readerURL == null) {
            Debug.logError("Cannot add reader with a null reader URL", module);
            return null;
        }

        ModelServiceReader reader = new ModelServiceReader(true, readerURL, null, delegator);
        return reader.getModelServices();
    }

    public static Map<String, ModelService> getModelServiceMap(ResourceHandler handler, Delegator delegator) {
        ModelServiceReader reader = new ModelServiceReader(false, null, handler, delegator);
        return reader.getModelServices();
    }

    private ModelServiceReader(boolean isFromURL, URL readerURL, ResourceHandler handler, Delegator delegator) {
        this.isFromURL = isFromURL;
        this.readerURL = readerURL;
        this.handler = handler;
        this.delegator = delegator;
    }

    private Map<String, ModelService> getModelServices() {
        UtilTimer utilTimer = new UtilTimer();
        Document document;
        if (this.isFromURL) {
            // utilTimer.timerString("Before getDocument in file " + readerURL);
            document = getDocument(readerURL);

            if (document == null) {
                return null;
            }
        } else {
            // utilTimer.timerString("Before getDocument in " + handler);
            try {
                document = handler.getDocument();
            } catch (GenericConfigException e) {
                Debug.logError(e, "Error getting XML document from resource", module);
                return null;
            }
        }

        Map<String, ModelService> modelServices = new HashMap<String, ModelService>();
        if (this.isFromURL) {// utilTimer.timerString("Before getDocumentElement in file " + readerURL);
        } else {// utilTimer.timerString("Before getDocumentElement in " + handler);
        }

        Element docElement = document.getDocumentElement();
        if (docElement == null) {
            return null;
        }

        docElement.normalize();

        String resourceLocation = handler.getLocation();
        try {
            resourceLocation = handler.getURL().toExternalForm();
        } catch (GenericConfigException e) {
            Debug.logError(e, "Could not get resource URL", module);
        }

        int i = 0;
        Node curChild = docElement.getFirstChild();
        if (curChild != null) {
            if (this.isFromURL) {
                utilTimer.timerString("Before start of service loop in file " + readerURL);
            } else {
                utilTimer.timerString("Before start of service loop in " + handler);
            }

            do {
                if (curChild.getNodeType() == Node.ELEMENT_NODE && "service".equals(curChild.getNodeName())) {
                    i++;
                    Element curServiceElement = (Element) curChild;
                    String serviceName = UtilXml.checkEmpty(curServiceElement.getAttribute("name"));

                    // check to see if service with same name has already been read
                    if (modelServices.containsKey(serviceName)) {
                        Debug.logWarning("Service " + serviceName + " is defined more than once, " +
                            "most recent will over-write previous definition(s)", module);
                    }

                    // utilTimer.timerString("  After serviceName -- " + i + " --");
                    ModelService service = createModelService(curServiceElement, resourceLocation);

                    // utilTimer.timerString("  After createModelService -- " + i + " --");
                    if (service != null) {
                        modelServices.put(serviceName, service);
                        // utilTimer.timerString("  After modelServices.put -- " + i + " --");
                        /*
                        int reqIn = service.getParameterNames(ModelService.IN_PARAM, false).size();
                        int optIn = service.getParameterNames(ModelService.IN_PARAM, true).size() - reqIn;
                        int reqOut = service.getParameterNames(ModelService.OUT_PARAM, false).size();
                        int optOut = service.getParameterNames(ModelService.OUT_PARAM, true).size() - reqOut;

                        if (Debug.verboseOn()) {
                            String msg = "-- getModelService: # " + i + " Loaded service: " + serviceName +
                                " (IN) " + reqIn + "/" + optIn + " (OUT) " + reqOut + "/" + optOut;

                            Debug.logVerbose(msg, module);
                        }
                        */
                    } else {
                        Debug.logWarning(
                            "-- -- SERVICE ERROR:getModelService: Could not create service for serviceName: " +
                            serviceName, module);
                    }

                }
            } while ((curChild = curChild.getNextSibling()) != null);
        } else {
            Debug.logWarning("No child nodes found.", module);
        }
        if (this.isFromURL) {
            utilTimer.timerString("Finished file " + readerURL + " - Total Services: " + i + " FINISHED");
            Debug.logInfo("Loaded [" + i + "] Services from " + readerURL, module);
        } else {
            utilTimer.timerString("Finished document in " + handler + " - Total Services: " + i + " FINISHED");
            if (Debug.infoOn()) {
                Debug.logInfo("Loaded [" + i + "] Services from " + resourceLocation, module);
            }
        }
        return modelServices;
    }

    private ModelService createModelService(Element serviceElement, String resourceLocation) {
        ModelService service = new ModelService();

        service.name = UtilXml.checkEmpty(serviceElement.getAttribute("name")).intern();
        service.definitionLocation = resourceLocation;
        service.engineName = UtilXml.checkEmpty(serviceElement.getAttribute("engine")).intern();
        service.location = UtilXml.checkEmpty(serviceElement.getAttribute("location")).intern();
        service.invoke = UtilXml.checkEmpty(serviceElement.getAttribute("invoke")).intern();
        service.semaphore = UtilXml.checkEmpty(serviceElement.getAttribute("semaphore")).intern();
        service.defaultEntityName = UtilXml.checkEmpty(serviceElement.getAttribute("default-entity-name")).intern();
        service.fromLoader = isFromURL ? readerURL.toExternalForm() : handler.getLoaderName();

        // these default to true; if anything but true, make false
        service.auth = "true".equalsIgnoreCase(serviceElement.getAttribute("auth"));
        service.export = "true".equalsIgnoreCase(serviceElement.getAttribute("export"));
        service.debug = "true".equalsIgnoreCase(serviceElement.getAttribute("debug"));

        // these defaults to false; if anything but false, make it true
        service.validate = !"false".equalsIgnoreCase(serviceElement.getAttribute("validate"));
        service.useTransaction = !"false".equalsIgnoreCase(serviceElement.getAttribute("use-transaction"));
        service.requireNewTransaction = !"false".equalsIgnoreCase(serviceElement.getAttribute("require-new-transaction"));
        if (service.requireNewTransaction && !service.useTransaction) {
            // requireNewTransaction implies that a transaction is used
            service.useTransaction = true;
            Debug.logWarning("In service definition [" + service.name + "] the value use-transaction has been changed from false to true as required when require-new-transaction is set to true", module);
        }
        service.hideResultInLog = !"false".equalsIgnoreCase(serviceElement.getAttribute("hideResultInLog"));        

        // set the semaphore sleep/wait times
        String semaphoreWaitStr = UtilXml.checkEmpty(serviceElement.getAttribute("semaphore-wait-seconds"));
        int semaphoreWait = 300;
        if (UtilValidate.isNotEmpty(semaphoreWaitStr)) {
            try {
                semaphoreWait = Integer.parseInt(semaphoreWaitStr);
            } catch (NumberFormatException e) {
                Debug.logWarning(e, "Setting semaphore-wait to 5 minutes (default)", module);
                semaphoreWait = 300;
            }
        }
        service.semaphoreWait = semaphoreWait;

        String semaphoreSleepStr = UtilXml.checkEmpty(serviceElement.getAttribute("semaphore-sleep"));
        int semaphoreSleep = 500;
        if (UtilValidate.isNotEmpty(semaphoreSleepStr)) {
            try {
                semaphoreSleep = Integer.parseInt(semaphoreSleepStr);
            } catch (NumberFormatException e) {
                Debug.logWarning(e, "Setting semaphore-sleep to 1/2 second (default)", module);
                semaphoreSleep = 500;
            }
        }
        service.semaphoreSleep = semaphoreSleep;

        // set the max retry field
        String maxRetryStr = UtilXml.checkEmpty(serviceElement.getAttribute("max-retry"));
        int maxRetry = -1;
        if (UtilValidate.isNotEmpty(maxRetryStr)) {
            try {
                maxRetry = Integer.parseInt(maxRetryStr);
            } catch (NumberFormatException e) {
                Debug.logWarning(e, "Setting maxRetry to -1 (default)", module);
                maxRetry = -1;
            }
        }
        service.maxRetry = maxRetry;

        // get the timeout and convert to int
        String timeoutStr = UtilXml.checkEmpty(serviceElement.getAttribute("transaction-timeout"), serviceElement.getAttribute("transaction-timout"));
        int timeout = 0;
        if (UtilValidate.isNotEmpty(timeoutStr)) {
            try {
                timeout = Integer.parseInt(timeoutStr);
            } catch (NumberFormatException e) {
                Debug.logWarning(e, "Setting timeout to 0 (default)", module);
                timeout = 0;
            }
        }
        service.transactionTimeout = timeout;                

        service.description = getCDATADef(serviceElement, "description");
        service.nameSpace = getCDATADef(serviceElement, "namespace");

        // construct the context
        service.contextInfo = new HashMap<String, ModelParam>();
        this.createNotification(serviceElement, service);
        this.createPermission(serviceElement, service);
        this.createPermGroups(serviceElement, service);
        this.createGroupDefs(serviceElement, service);
        this.createImplDefs(serviceElement, service);
        this.createAutoAttrDefs(serviceElement, service);
        this.createAttrDefs(serviceElement, service);
        this.createOverrideDefs(serviceElement, service);
        // Get metrics.
        Element metricsElement = UtilXml.firstChildElement(serviceElement, "metric");
        if (metricsElement != null) {
            service.metrics = MetricsFactory.getInstance(metricsElement);
        }
        return service;
    }

    private String getCDATADef(Element baseElement, String tagName) {
        String value = "";
        NodeList nl = baseElement.getElementsByTagName(tagName);

        // if there are more then one decriptions we will use only the first one
        if (nl.getLength() > 0) {
            Node n = nl.item(0);
            NodeList childNodes = n.getChildNodes();

            if (childNodes.getLength() > 0) {
                Node cdata = childNodes.item(0);

                value = UtilXml.checkEmpty(cdata.getNodeValue());
            }
        }
        return value;
    }

    private void createNotification(Element baseElement, ModelService model) {
        List<? extends Element> n = UtilXml.childElementList(baseElement, "notification");
        // default notification groups
        ModelNotification nSuccess = new ModelNotification();
        nSuccess.notificationEvent = "success";
        nSuccess.notificationGroupName = "default.success." + model.fromLoader;
        model.notifications.add(nSuccess);

        ModelNotification nFail = new ModelNotification();
        nFail.notificationEvent = "fail";
        nFail.notificationGroupName = "default.fail." + model.fromLoader;
        model.notifications.add(nFail);

        ModelNotification nError = new ModelNotification();
        nError.notificationEvent = "error";
        nError.notificationGroupName = "default.error." + model.fromLoader;
        model.notifications.add(nError);

        if (n != null) {
            for (Element e: n) {
                ModelNotification notify = new ModelNotification();
                notify.notificationEvent = e.getAttribute("event");
                notify.notificationGroupName = e.getAttribute("group");
                model.notifications.add(notify);
            }
        }
    }

    private void createPermission(Element baseElement, ModelService model) {
        Element e = UtilXml.firstChildElement(baseElement, "permission-service");
        if (e != null) {
            model.permissionServiceName = e.getAttribute("service-name");
            model.permissionMainAction = e.getAttribute("main-action");
            model.permissionResourceDesc = e.getAttribute("resource-description");
            model.auth = true; // auth is always required when permissions are set
        }
    }

    private void createPermGroups(Element baseElement, ModelService model) {
        for (Element element: UtilXml.childElementList(baseElement, "required-permissions")) {
            ModelPermGroup group = new ModelPermGroup();
            group.joinType = element.getAttribute("join-type");
            createGroupPermissions(element, group, model);
            model.permissionGroups.add(group);
        }
    }

    private void createGroupPermissions(Element baseElement, ModelPermGroup group, ModelService service) {
        // create the simple permissions
        for (Element element: UtilXml.childElementList(baseElement, "check-permission")) {
            ModelPermission perm = new ModelPermission();
            perm.nameOrRole = element.getAttribute("permission").intern();
            perm.action = element.getAttribute("action").intern();
            if (UtilValidate.isNotEmpty(perm.action)) {
                perm.permissionType = ModelPermission.ENTITY_PERMISSION;
            } else {
                perm.permissionType = ModelPermission.PERMISSION;
            }
            perm.serviceModel = service;
            group.permissions.add(perm);
        }

        // create the role member permissions
        for (Element element: UtilXml.childElementList(baseElement, "check-role-member")) {
            ModelPermission perm = new ModelPermission();
            perm.permissionType = ModelPermission.ROLE_MEMBER;
            perm.nameOrRole = element.getAttribute("role-type").intern();
            perm.serviceModel = service;
            group.permissions.add(perm);
        }
        // Create the permissions based on permission services
        for (Element element : UtilXml.childElementList(baseElement, "permission-service")) {
            ModelPermission perm = new ModelPermission();
            if (baseElement != null) {
                perm.permissionType = ModelPermission.PERMISSION_SERVICE;
                perm.permissionServiceName = element.getAttribute("service-name");
                perm.action = element.getAttribute("main-action");
                perm.permissionResourceDesc = element.getAttribute("resource-description");
                perm.auth = true; // auth is always required when permissions are set
                perm.serviceModel = service;
                group.permissions.add(perm);
            }
        }
    }

    private void createGroupDefs(Element baseElement, ModelService service) {
        List<? extends Element> group = UtilXml.childElementList(baseElement, "group");
        if (UtilValidate.isNotEmpty(group)) {
            Element groupElement = group.get(0);
            groupElement.setAttribute("name", "_" + service.name + ".group");
            service.internalGroup = new GroupModel(groupElement);
            service.invoke = service.internalGroup.getGroupName();
            if (Debug.verboseOn()) Debug.logVerbose("Created INTERNAL GROUP model [" + service.internalGroup + "]", module);
        }
    }

    private void createImplDefs(Element baseElement, ModelService service) {
        for (Element implement: UtilXml.childElementList(baseElement, "implements")) {
            String serviceName = UtilXml.checkEmpty(implement.getAttribute("service")).intern();
            boolean optional = UtilXml.checkBoolean(implement.getAttribute("optional"), false);
            if (serviceName.length() > 0)
                service.implServices.add(new ModelServiceIface(serviceName, optional));
                //service.implServices.add(serviceName);
        }
    }

    private void createAutoAttrDefs(Element baseElement, ModelService service) {
        for (Element element: UtilXml.childElementList(baseElement, "auto-attributes")) {
            createAutoAttrDef(element, service);
        }
    }

    private void createAutoAttrDef(Element autoElement, ModelService service) {
        // get the entity name; first from the auto-attributes then from the service def
        String entityName = UtilXml.checkEmpty(autoElement.getAttribute("entity-name"));
        if (UtilValidate.isEmpty(entityName)) {
            entityName = service.defaultEntityName;
            if (UtilValidate.isEmpty(entityName)) {
                Debug.logWarning("Auto-Attribute does not specify an entity-name; not default-entity on service definition", module);
            }
        }

        // get the include type 'pk|nonpk|all'
        String includeType = UtilXml.checkEmpty(autoElement.getAttribute("include"));
        boolean includePk = "pk".equals(includeType) || "all".equals(includeType);
        boolean includeNonPk = "nonpk".equals(includeType) || "all".equals(includeType);

        if (delegator == null) {
            Debug.logWarning("Cannot use auto-attribute fields with a null delegator", module);
        }

        if (delegator != null && entityName != null) {
            Map<String, ModelParam> modelParamMap = new LinkedHashMap<String, ModelParam>();
            try {
                ModelEntity entity = delegator.getModelEntity(entityName);
                if (entity == null) {
                    throw new GeneralException("Could not find entity with name [" + entityName + "]");
                }
                Iterator<ModelField> fieldsIter = entity.getFieldsIterator();
                if (fieldsIter != null) {
                    while (fieldsIter.hasNext()) {
                        ModelField field = fieldsIter.next();
                        if ((!field.getIsAutoCreatedInternal()) && ((field.getIsPk() && includePk) || (!field.getIsPk() && includeNonPk))) {
                            ModelFieldType fieldType = delegator.getEntityFieldType(entity, field.getType());
                            if (fieldType == null) {
                                throw new GeneralException("Null field type from delegator for entity [" + entityName + "]");
                            }
                            ModelParam param = new ModelParam();
                            param.entityName = entityName;
                            param.fieldName = field.getName();
                            param.name = field.getName();
                            param.type = fieldType.getJavaType();
                            // this is a special case where we use something different in the service layer than we do in the entity/data layer
                            if ("java.sql.Blob".equals(param.type)) {
                                param.type = "java.nio.ByteBuffer";
                            }
                            param.mode = UtilXml.checkEmpty(autoElement.getAttribute("mode")).intern();
                            param.optional = "true".equalsIgnoreCase(autoElement.getAttribute("optional")); // default to true
                            param.formDisplay = !"false".equalsIgnoreCase(autoElement.getAttribute("form-display")); // default to false
                            param.allowHtml = UtilXml.checkEmpty(autoElement.getAttribute("allow-html"), "none").intern(); // default to none
                            modelParamMap.put(field.getName(), param);
                        }
                    }

                    // get the excludes list; and remove those from the map
                    List<? extends Element> excludes = UtilXml.childElementList(autoElement, "exclude");
                    if (excludes != null) {
                        for (Element exclude: excludes) {
                            modelParamMap.remove(UtilXml.checkEmpty(exclude.getAttribute("field-name")));
                        }
                    }

                    // now add in all the remaining params
                    for (ModelParam thisParam: modelParamMap.values()) {
                        //Debug.logInfo("Adding Param to " + service.name + ": " + thisParam.name + " [" + thisParam.mode + "] " + thisParam.type + " (" + thisParam.optional + ")", module);
                        service.addParam(thisParam);
                    }
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, "Problem loading auto-attributes [" + entityName + "] for " + service.name, module);
            } catch (GeneralException e) {
                Debug.logError(e, "Cannot load auto-attributes : " + e.getMessage() + " for " + service.name, module);
            }
        }
    }

    private void createAttrDefs(Element baseElement, ModelService service) {
        // Add in the defined attributes (override the above defaults if specified)
        for (Element attribute: UtilXml.childElementList(baseElement, "attribute")) {
            ModelParam param = new ModelParam();

            param.name = UtilXml.checkEmpty(attribute.getAttribute("name")).intern();
            param.description = getCDATADef(attribute, "description");
            param.type = UtilXml.checkEmpty(attribute.getAttribute("type")).intern();
            param.mode = UtilXml.checkEmpty(attribute.getAttribute("mode")).intern();
            param.entityName = UtilXml.checkEmpty(attribute.getAttribute("entity-name")).intern();
            param.fieldName = UtilXml.checkEmpty(attribute.getAttribute("field-name")).intern();
            param.requestAttributeName = UtilXml.checkEmpty(attribute.getAttribute("request-attribute-name")).intern();
            param.sessionAttributeName = UtilXml.checkEmpty(attribute.getAttribute("session-attribute-name")).intern();
            param.stringMapPrefix = UtilXml.checkEmpty(attribute.getAttribute("string-map-prefix")).intern();
            param.stringListSuffix = UtilXml.checkEmpty(attribute.getAttribute("string-list-suffix")).intern();
            param.formLabel = attribute.hasAttribute("form-label")?attribute.getAttribute("form-label").intern():null;
            param.optional = "true".equalsIgnoreCase(attribute.getAttribute("optional")); // default to true
            param.formDisplay = !"false".equalsIgnoreCase(attribute.getAttribute("form-display")); // default to false
            param.allowHtml = UtilXml.checkEmpty(attribute.getAttribute("allow-html"), "none").intern(); // default to none

            // default value
            String defValue = attribute.getAttribute("default-value");
            if (UtilValidate.isNotEmpty(defValue)) {
                if (Debug.verboseOn()) Debug.logVerbose("Got a default-value [" + defValue + "] for service attribute [" + service.name + "." + param.name + "]", module);
                param.setDefaultValue(defValue.intern());
            }

            // set the entity name to the default if not specified
            if (param.entityName.length() == 0) {
                param.entityName = service.defaultEntityName;
            }

            // set the field-name to the name if entity name is specified but no field-name
            if (param.fieldName.length() == 0 && param.entityName.length() > 0) {
                param.fieldName = param.name;
            }

            // set the validators
            this.addValidators(attribute, param);
            service.addParam(param);
        }

        // Add the default optional parameters
        ModelParam def;

        // responseMessage
        def = new ModelParam();
        def.name = ModelService.RESPONSE_MESSAGE;
        def.type = "String";
        def.mode = "OUT";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
        // errorMessage
        def = new ModelParam();
        def.name = ModelService.ERROR_MESSAGE;
        def.type = "String";
        def.mode = "OUT";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
        // errorMessageList
        def = new ModelParam();
        def.name = ModelService.ERROR_MESSAGE_LIST;
        def.type = "java.util.List";
        def.mode = "OUT";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
        // successMessage
        def = new ModelParam();
        def.name = ModelService.SUCCESS_MESSAGE;
        def.type = "String";
        def.mode = "OUT";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
        // successMessageList
        def = new ModelParam();
        def.name = ModelService.SUCCESS_MESSAGE_LIST;
        def.type = "java.util.List";
        def.mode = "OUT";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
        // userLogin
        def = new ModelParam();
        def.name = "userLogin";
        def.type = "org.apache.ofbiz.entity.GenericValue";
        def.mode = "INOUT";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
        // login.username
        def = new ModelParam();
        def.name = "login.username";
        def.type = "String";
        def.mode = "IN";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
        // login.password
        def = new ModelParam();
        def.name = "login.password";
        def.type = "String";
        def.mode = "IN";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
        // Locale
        def = new ModelParam();
        def.name = "locale";
        def.type = "java.util.Locale";
        def.mode = "INOUT";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
        // timeZone
        def = new ModelParam();
        def.name = "timeZone";
        def.type = "java.util.TimeZone";
        def.mode = "INOUT";
        def.optional = true;
        def.internal = true;
        service.addParam(def);
    }

    private void createOverrideDefs(Element baseElement, ModelService service) {
        for (Element overrideElement: UtilXml.childElementList(baseElement, "override")) {
            String name = UtilXml.checkEmpty(overrideElement.getAttribute("name"));
            ModelParam param = service.getParam(name);
            boolean directToParams = true;
            if (param == null) {
                if (!service.inheritedParameters && (service.implServices.size() > 0 || "group".equals(service.engineName))) {
                    // create a temp def to place in the ModelService
                    // this will get read when we read implemented services
                    directToParams = false;
                    param = new ModelParam();
                    param.name = name;
                } else {
                    Debug.logWarning("No parameter found for override parameter named: " + name + " in service " + service.name, module);
                }
            }

            if (param != null) {
                // set only modified values
                if (UtilValidate.isNotEmpty(overrideElement.getAttribute("type"))) {
                    param.type = UtilXml.checkEmpty(overrideElement.getAttribute("type")).intern();
                }
                if (UtilValidate.isNotEmpty(overrideElement.getAttribute("mode"))) {
                    param.mode = UtilXml.checkEmpty(overrideElement.getAttribute("mode")).intern();
                }
                if (UtilValidate.isNotEmpty(overrideElement.getAttribute("entity-name"))) {
                   param.entityName = UtilXml.checkEmpty(overrideElement.getAttribute("entity-name")).intern();
                }
                if (UtilValidate.isNotEmpty(overrideElement.getAttribute("field-name"))) {
                    param.fieldName = UtilXml.checkEmpty(overrideElement.getAttribute("field-name")).intern();
                }
                if (UtilValidate.isNotEmpty(overrideElement.getAttribute("form-label"))) {
                    param.formLabel = UtilXml.checkEmpty(overrideElement.getAttribute("form-label")).intern();
                }
                if (UtilValidate.isNotEmpty(overrideElement.getAttribute("optional"))) {
                    param.optional = "true".equalsIgnoreCase(overrideElement.getAttribute("optional")); // default to true
                    param.overrideOptional = true;
                }
                if (UtilValidate.isNotEmpty(overrideElement.getAttribute("form-display"))) {
                    param.formDisplay = !"false".equalsIgnoreCase(overrideElement.getAttribute("form-display")); // default to false
                    param.overrideFormDisplay = true;
                }

                if (UtilValidate.isNotEmpty(overrideElement.getAttribute("allow-html"))) {
                    param.allowHtml = UtilXml.checkEmpty(overrideElement.getAttribute("allow-html")).intern();
                }

                // default value
                String defValue = overrideElement.getAttribute("default-value");
                if (UtilValidate.isNotEmpty(defValue)) {
                    param.setDefaultValue(defValue);
                }

                // override validators
                this.addValidators(overrideElement, param);

                if (directToParams) {
                    service.addParam(param);
                } else {
                    service.overrideParameters.add(param);
                }
            }
        }
    }

    private void addValidators(Element attribute, ModelParam param) {
        List<? extends Element> validateElements = UtilXml.childElementList(attribute, "type-validate");
        if (UtilValidate.isNotEmpty(validateElements)) {
            // always clear out old ones; never append
            param.validators = new LinkedList<ModelParamValidator>();

            Element validate = validateElements.get(0);
            String methodName = validate.getAttribute("method").intern();
            String className = validate.getAttribute("class").intern();

            Element fail = UtilXml.firstChildElement(validate, "fail-message");
            if (fail != null) {
                String message = fail.getAttribute("message").intern();
                param.addValidator(className, methodName, message);
            } else {
                fail = UtilXml.firstChildElement(validate, "fail-property");
                if (fail != null) {
                    String resource = fail.getAttribute("resource").intern();
                    String property = fail.getAttribute("property").intern();
                    param.addValidator(className, methodName, resource, property);
                }
            }
        }
    }

    private Document getDocument(URL url) {
        if (url == null)
            return null;
        Document document = null;

        try {
            document = UtilXml.readXmlDocument(url, true, true);
        } catch (SAXException sxe) {
            // Error generated during parsing)
            Exception x = sxe;

            if (sxe.getException() != null)
                x = sxe.getException();
            x.printStackTrace();
        } catch (ParserConfigurationException pce) {
            // Parser with specified options can't be built
            pce.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

        return document;
    }
}
