/*******************************************************************************
 * 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.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.ofbiz.base.config.GenericConfigException;
import org.ofbiz.base.config.ResourceHandler;
import org.ofbiz.base.metrics.MetricsFactory;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.GeneralException;
import org.ofbiz.base.util.UtilTimer;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.model.ModelEntity;
import org.ofbiz.entity.model.ModelField;
import org.ofbiz.entity.model.ModelFieldType;
import org.ofbiz.service.ModelParam.ModelParamValidator;
import org.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.isEmpty(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.isEmpty(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.isEmpty(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.isEmpty(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.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;
    }
}
