/*
 * Copyright 2001-2008 The Apache Software Foundation.
 * 
 * Licensed 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.juddi.validation;

import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.xml.ws.Holder;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.juddi.api_v3.AccessPointType;
import org.apache.juddi.api_v3.DeleteClerk;
import org.apache.juddi.api_v3.DeleteNode;
import org.apache.juddi.api_v3.DeletePublisher;
import org.apache.juddi.api_v3.SavePublisher;
import org.apache.juddi.config.AppConfig;
import org.apache.juddi.config.Constants;
import org.apache.juddi.config.Install;
import org.apache.juddi.config.PersistenceManager;
import org.apache.juddi.config.Property;
import org.apache.juddi.keygen.KeyGenerator;
import org.apache.juddi.keygen.KeyGeneratorFactory;
import org.apache.juddi.mapping.MappingModelToApi;
import org.apache.juddi.model.Publisher;
import org.apache.juddi.model.Tmodel;
import org.apache.juddi.model.UddiEntity;
import org.apache.juddi.model.UddiEntityPublisher;
import org.apache.juddi.query.FindBusinessByPublisherQuery;
import org.apache.juddi.query.FindTModelByPublisherQuery;
import org.apache.juddi.v3.client.UDDIConstants;
import org.apache.juddi.v3.client.UDDIConstantsV2;
import org.apache.juddi.v3.client.config.TokenResolver;
import org.apache.juddi.v3.client.cryptor.CryptorFactory;
import org.apache.juddi.v3.client.cryptor.DigSigUtil;
import org.apache.juddi.v3.error.AssertionNotFoundException;
import org.apache.juddi.v3.error.ErrorMessage;
import org.apache.juddi.v3.error.FatalErrorException;
import org.apache.juddi.v3.error.InvalidKeyPassedException;
import org.apache.juddi.v3.error.InvalidProjectionException;
import org.apache.juddi.v3.error.KeyUnavailableException;
import org.apache.juddi.v3.error.MaxEntitiesExceededException;
import org.apache.juddi.v3.error.UserMismatchException;
import org.apache.juddi.v3.error.ValueNotAllowedException;
import org.uddi.api_v3.AccessPoint;
import org.uddi.api_v3.AddPublisherAssertions;
import org.uddi.api_v3.AddressLine;
import org.uddi.api_v3.BindingTemplate;
import org.uddi.api_v3.BusinessEntity;
import org.uddi.api_v3.BusinessService;
import org.uddi.api_v3.DeleteBinding;
import org.uddi.api_v3.DeleteBusiness;
import org.uddi.api_v3.DeletePublisherAssertions;
import org.uddi.api_v3.DeleteService;
import org.uddi.api_v3.DeleteTModel;
import org.uddi.api_v3.Description;
import org.uddi.api_v3.DiscoveryURL;
import org.uddi.api_v3.Email;
import org.uddi.api_v3.HostingRedirector;
import org.uddi.api_v3.KeyedReference;
import org.uddi.api_v3.KeyedReferenceGroup;
import org.uddi.api_v3.Name;
import org.uddi.api_v3.OverviewDoc;
import org.uddi.api_v3.OverviewURL;
import org.uddi.api_v3.Phone;
import org.uddi.api_v3.SaveBinding;
import org.uddi.api_v3.SaveBusiness;
import org.uddi.api_v3.SaveService;
import org.uddi.api_v3.SaveTModel;
import org.uddi.api_v3.TModel;
import org.uddi.repl_v3.ReplicationConfiguration;
import org.uddi.sub_v3.Subscription;
import org.uddi.v3_service.DispositionReportFaultMessage;

/**
 * Provides validation of publish requests to Juddi
 *
 * @author <a href="mailto:jfaath@apache.org">Jeff Faath</a>
 * @author <a href="mailto:tcunning@apache.org">Tom Cunningham</a>
 * @author <a href="mailto:alexoree@apache.org">Alex O'Ree</a> Modified March
 * 2013 to validate string length and ref integrity
 *
 * Advisory, be careful calling AppConfig.getConfiguration() from within
 * validation functions, it may inadvertently cause infinite loops during the
 * Install phase
 * @see Install
 */
public class ValidatePublish extends ValidateUDDIApi {

        /**
         * This flag will add additional output to stdout for debugging
         * purposes, set this to true if
         */
        private Log log = LogFactory.getLog(this.getClass());

        /**
         * used from Install class
         *
         * @param publisher
         * @param nodeid
         * @see Install
         */
        public ValidatePublish(UddiEntityPublisher publisher, String nodeid) {
                super(publisher, nodeid);
        }

        public ValidatePublish(UddiEntityPublisher publisher) {
                super(publisher);
        }

        public void validateDeleteBusiness(EntityManager em, DeleteBusiness body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<String> entityKeyList = body.getBusinessKey();
                if (entityKeyList == null || entityKeyList.size() == 0) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.NoKeys"));
                }

                HashSet<String> dupCheck = new HashSet<String>();
                int i = 0;
                for (String entityKey : entityKeyList) {

                        // Per section 4.4: keys must be case-folded
                        entityKey = entityKey.toLowerCase();
                        entityKeyList.set(i, entityKey);

                        boolean inserted = dupCheck.add(entityKey);
                        if (!inserted) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.DuplicateKey", entityKey));
                        }

                        Object obj = em.find(org.apache.juddi.model.BusinessEntity.class, entityKey);
                        if (obj == null) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.BusinessNotFound", entityKey));
                        }

                        if (!publisher.isOwner((UddiEntity) obj) && !((Publisher) publisher).isAdmin()) {
                                throw new UserMismatchException(new ErrorMessage("errors.usermismatch.InvalidOwner", entityKey));
                        }

                        i++;
                }
        }

        public void validateDeleteService(EntityManager em, DeleteService body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<String> entityKeyList = body.getServiceKey();
                if (entityKeyList == null || entityKeyList.size() == 0) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.NoKeys"));
                }

                HashSet<String> dupCheck = new HashSet<String>();
                int i = 0;
                for (String entityKey : entityKeyList) {

                        // Per section 4.4: keys must be case-folded
                        entityKey = entityKey.toLowerCase();
                        entityKeyList.set(i, entityKey);

                        boolean inserted = dupCheck.add(entityKey);
                        if (!inserted) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.DuplicateKey", entityKey));
                        }

                        Object obj = em.find(org.apache.juddi.model.BusinessService.class, entityKey);
                        if (obj == null) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.ServiceNotFound", entityKey));
                        }

                        //if you're are the owner, access granted
                        //if you are an admin && this item belongs to this node, access granted
                        //else denied
                        AccessCheck(obj, entityKey);
                        i++;
                }
        }

        public void validateDeleteBinding(EntityManager em, DeleteBinding body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<String> entityKeyList = body.getBindingKey();
                if (entityKeyList == null || entityKeyList.size() == 0) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.NoKeys"));
                }

                // Checking for duplicates and existence
                HashSet<String> dupCheck = new HashSet<String>();
                int i = 0;
                for (String entityKey : entityKeyList) {
                        validateKeyLength(entityKey);
                        // Per section 4.4: keys must be case-folded
                        entityKey = entityKey.toLowerCase();
                        entityKeyList.set(i, entityKey);

                        boolean inserted = dupCheck.add(entityKey);
                        if (!inserted) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.DuplicateKey", entityKey));
                        }

                        Object obj = em.find(org.apache.juddi.model.BindingTemplate.class, entityKey);
                        if (obj == null) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.BindingTemplateNotFound", entityKey));
                        }

                        AccessCheck(obj, entityKey);

                        i++;
                }
        }

        public void validateDeleteTModel(EntityManager em, DeleteTModel body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<String> entityKeyList = body.getTModelKey();
                if (entityKeyList == null || entityKeyList.size() == 0) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.NoKeys"));
                }

                HashSet<String> dupCheck = new HashSet<String>();
                int i = 0;
                for (String entityKey : entityKeyList) {
                        validateKeyLength(entityKey);
                        // Per section 4.4: keys must be case-folded
                        entityKey = entityKey.toLowerCase();
                        entityKeyList.set(i, entityKey);

                        boolean inserted = dupCheck.add(entityKey);
                        if (!inserted) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.DuplicateKey", entityKey));
                        }

                        Object obj = em.find(org.apache.juddi.model.Tmodel.class, entityKey);
                        if (obj == null) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.TModelNotFound", entityKey));
                        }

                        AccessCheck(obj, entityKey);

                        i++;
                }
        }

        private void AccessCheck(Object obj, String entityKey) throws UserMismatchException {
                boolean accessCheck = false; //assume access denied
                if (!((UddiEntity) obj).getNodeId().equals(nodeID)) {
                        //prevent changes to data owned by another node in a replicated environment
                        //even if you're the boss
                        throw new UserMismatchException(new ErrorMessage("errors.usermismatch.InvalidNode", entityKey + " Owning Node: " + ((UddiEntity) obj).getNodeId()
                                + ", this node: " + nodeID));
                }

                if (publisher.isOwner((UddiEntity) obj) && nodeID.equals(((UddiEntity) obj).getNodeId())) {
                        accessCheck = true;

                }
                //if i'm an admin, let me edit stuff on this node, but only stuff that's owned by this node
                if (((Publisher) publisher).isAdmin()
                        && nodeID.equals(((UddiEntity) obj).getNodeId())) {
                        accessCheck = true;
                }

                if (!accessCheck) {
                        throw new UserMismatchException(new ErrorMessage("errors.usermismatch.InvalidOwner", entityKey));
                }

        }

        public void validateDeletePublisherAssertions(EntityManager em, DeletePublisherAssertions body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<org.uddi.api_v3.PublisherAssertion> entityList = body.getPublisherAssertion();
                if (entityList == null || entityList.size() == 0) {
                        throw new AssertionNotFoundException(new ErrorMessage("errors.pubassertion.NoPubAssertions"));
                }

                for (org.uddi.api_v3.PublisherAssertion entity : entityList) {
                        validateKeyLength(entity.getFromKey());
                        validateKeyLength(entity.getToKey());
                        validatePublisherAssertion(em, entity);

                        org.apache.juddi.model.PublisherAssertionId pubAssertionId = new org.apache.juddi.model.PublisherAssertionId(entity.getFromKey(), entity.getToKey());
                        Object obj = em.find(org.apache.juddi.model.PublisherAssertion.class, pubAssertionId);
                        if (obj == null) {
                                throw new AssertionNotFoundException(new ErrorMessage("errors.pubassertion.AssertionNotFound", entity.getFromKey() + ", " + entity.getToKey()));
                        } else {
                                org.apache.juddi.model.PublisherAssertion pubAssertion = (org.apache.juddi.model.PublisherAssertion) obj;
                                org.uddi.api_v3.KeyedReference keyedRef = entity.getKeyedReference();
                                if (keyedRef == null) {
                                        throw new AssertionNotFoundException(new ErrorMessage("errors.pubassertion.AssertionNotFound", entity.getFromKey() + ", " + entity.getToKey()));
                                }

                                if (!pubAssertion.getTmodelKey().equalsIgnoreCase(keyedRef.getTModelKey())
                                        || !pubAssertion.getKeyName().equalsIgnoreCase(keyedRef.getKeyName())
                                        || !pubAssertion.getKeyValue().equalsIgnoreCase(keyedRef.getKeyValue())) {
                                        throw new AssertionNotFoundException(new ErrorMessage("errors.pubassertion.AssertionNotFound", entity.getFromKey() + ", " + entity.getToKey()));
                                }
                                //JUDDI-908
                                if (!publisher.isOwner(pubAssertion.getBusinessEntityByToKey())
                                        && !publisher.isOwner(pubAssertion.getBusinessEntityByFromKey())) {
                                        throw new UserMismatchException(new ErrorMessage("errors.usermismatch.assertion"));
                                }

                        }

                }
        }

        public void validateSaveBusiness(EntityManager em, SaveBusiness body, Configuration config, UddiEntityPublisher publisher) throws DispositionReportFaultMessage {

                if (config == null) {
                        try {
                                config = AppConfig.getConfiguration();
                        } catch (ConfigurationException ce) {
                                log.error("Could not optain config. " + ce.getMessage(), ce);
                        }
                }
                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<org.uddi.api_v3.BusinessEntity> entityList = body.getBusinessEntity();
                if (entityList == null || entityList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.savebusiness.NoInput"));
                }

                for (org.uddi.api_v3.BusinessEntity entity : entityList) {
                        validateBusinessEntity(em, entity, config, publisher);

                }
                validateCheckedTModelsBE(entityList, config);
        }

        public void validateSaveBusinessMax(EntityManager em) throws DispositionReportFaultMessage {

                //Obtain the maxSettings for this publisher or get the defaults
                Publisher publisher = em.find(Publisher.class, getPublisher().getAuthorizedName());
                Integer maxBusinesses = publisher.getMaxBusinesses();
                try {
                        if (maxBusinesses == null) {
                                if (AppConfig.getConfiguration().containsKey(Property.JUDDI_MAX_BUSINESSES_PER_PUBLISHER)) {
                                        maxBusinesses = AppConfig.getConfiguration().getInteger(Property.JUDDI_MAX_BUSINESSES_PER_PUBLISHER, -1);
                                } else {
                                        maxBusinesses = -1;
                                }
                        }
                } catch (ConfigurationException e) {
                        log.error(e.getMessage(), e);
                        maxBusinesses = -1; //in case the configuration is not available
                }
                //if we have the maxBusinesses set for this publisher then we need to make sure we did not exceed it.
                if (maxBusinesses > 0) {
                        //get the businesses owned by this publisher
                        List<?> businessKeysFound = FindBusinessByPublisherQuery.select(em, null, publisher, null);
                        if (businessKeysFound != null && businessKeysFound.size() > maxBusinesses) {
                                throw new MaxEntitiesExceededException(new ErrorMessage("errors.save.maxBusinessesExceeded"));
                        }
                }

        }

        public void validateSaveService(EntityManager em, SaveService body, Configuration config, UddiEntityPublisher publisher) throws DispositionReportFaultMessage {

                if (config == null) {
                        try {
                                config = AppConfig.getConfiguration();
                        } catch (ConfigurationException ce) {
                                log.error("Could not optain config. " + ce.getMessage(), ce);
                        }
                }
                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<org.uddi.api_v3.BusinessService> entityList = body.getBusinessService();
                if (entityList == null || entityList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.saveservice.NoInput"));
                }

                for (org.uddi.api_v3.BusinessService entity : entityList) {
                        // Entity specific data validation
                        validateBusinessService(em, entity, null, config, publisher);

                }
                validateCheckedTModelsBS(entityList, config);
        }

        public void validateSaveServiceMax(EntityManager em, String businessKey) throws DispositionReportFaultMessage {

                //Obtain the maxSettings for this publisher or get the defaults
                Publisher publisher = em.find(Publisher.class, getPublisher().getAuthorizedName());
                Integer maxServices = publisher.getMaxBusinesses();
                try {
                        if (maxServices == null) {
                                if (AppConfig.getConfiguration().containsKey(Property.JUDDI_MAX_SERVICES_PER_BUSINESS)) {
                                        maxServices = AppConfig.getConfiguration().getInteger(Property.JUDDI_MAX_SERVICES_PER_BUSINESS, -1);
                                } else {
                                        maxServices = -1;
                                }
                        }
                } catch (ConfigurationException e) {
                        log.error(e.getMessage(), e);
                        maxServices = -1; //incase the configuration isn't available
                }
                //if we have the maxServices set for a business then we need to make sure we did not exceed it.
                if (maxServices > 0) {
                        //get the businesses owned by this publisher
                        org.apache.juddi.model.BusinessEntity modelBusinessEntity = em.find(org.apache.juddi.model.BusinessEntity.class, businessKey);
                        if (modelBusinessEntity.getBusinessServices() != null && modelBusinessEntity.getBusinessServices().size() > maxServices) {
                                throw new MaxEntitiesExceededException(new ErrorMessage("errors.save.maxServicesExceeded"));
                        }
                }
        }

        public void validateSaveBinding(EntityManager em, SaveBinding body, Configuration config, UddiEntityPublisher publisher) throws DispositionReportFaultMessage {

                if (config == null) {
                        try {
                                config = AppConfig.getConfiguration();
                        } catch (ConfigurationException ce) {
                                log.error("Could not optain config. " + ce.getMessage(), ce);
                        }
                }
                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<org.uddi.api_v3.BindingTemplate> entityList = body.getBindingTemplate();
                if (entityList == null || entityList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.savebinding.NoInput"));
                }

                for (org.uddi.api_v3.BindingTemplate entity : entityList) {
                        validateBindingTemplate(em, entity, null, config, publisher);

                }
                validateCheckedTModelsBT(entityList, config);
        }

        public void validateSaveBindingMax(EntityManager em, String serviceKey) throws DispositionReportFaultMessage {

                //Obtain the maxSettings for this publisher or get the defaults
                Publisher publisher = em.find(Publisher.class, getPublisher().getAuthorizedName());
                Integer maxBindings = publisher.getMaxBindingsPerService();
                try {
                        if (maxBindings == null) {
                                if (AppConfig.getConfiguration().containsKey(Property.JUDDI_MAX_BINDINGS_PER_SERVICE)) {
                                        maxBindings = AppConfig.getConfiguration().getInteger(Property.JUDDI_MAX_BINDINGS_PER_SERVICE, -1);
                                } else {
                                        maxBindings = -1;
                                }
                        }
                } catch (ConfigurationException e) {
                        log.error(e.getMessage(), e);
                        maxBindings = -1; //incase the config isn't available
                }
                //if we have the maxBindings set for a service then we need to make sure we did not exceed it.
                if (maxBindings > 0) {
                        //get the bindings owned by this service
                        org.apache.juddi.model.BusinessService modelBusinessService = em.find(org.apache.juddi.model.BusinessService.class, serviceKey);
                        if (modelBusinessService.getBindingTemplates() != null && modelBusinessService.getBindingTemplates().size() > maxBindings) {
                                throw new MaxEntitiesExceededException(new ErrorMessage("errors.save.maxBindingsExceeded"));
                        }
                }
        }

        public void validateSaveTModel(EntityManager em, SaveTModel body, Configuration config, UddiEntityPublisher publisher) throws DispositionReportFaultMessage {

                if (config == null) {
                        try {
                                config = AppConfig.getConfiguration();
                        } catch (ConfigurationException ce) {
                                log.error("Could not optain config. " + ce.getMessage(), ce);
                        }
                }
                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<org.uddi.api_v3.TModel> entityList = body.getTModel();
                if (entityList == null || entityList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.savetmodel.NoInput"));
                }

                for (org.uddi.api_v3.TModel entity : entityList) {
                        validateTModel(em, entity, config, publisher);

                }
                validateCheckedTModelsTM(entityList, config);
        }

        public void validateSaveTModelMax(EntityManager em) throws DispositionReportFaultMessage {

                //Obtain the maxSettings for this publisher or get the defaults
                Publisher publisher = em.find(Publisher.class, getPublisher().getAuthorizedName());
                Integer maxTModels = publisher.getMaxTmodels();
                try {
                        if (maxTModels == null) {
                                if (AppConfig.getConfiguration().containsKey(Property.JUDDI_MAX_TMODELS_PER_PUBLISHER)) {
                                        maxTModels = AppConfig.getConfiguration().getInteger(Property.JUDDI_MAX_TMODELS_PER_PUBLISHER, -1);
                                } else {
                                        maxTModels = -1;
                                }
                        }
                } catch (ConfigurationException e) {
                        log.error(e.getMessage(), e);
                        maxTModels = -1; //incase the config isn't available
                }
                //if we have the TModels set for a publisher then we need to make sure we did not exceed it.
                if (maxTModels > 0) {
                        //get the tmodels owned by this publisher
                        List<?> tmodelKeysFound = FindTModelByPublisherQuery.select(em, null, publisher, null);
                        if (tmodelKeysFound != null && tmodelKeysFound.size() > maxTModels) {
                                throw new MaxEntitiesExceededException(new ErrorMessage("errors.save.maxTModelsExceeded"));
                        }
                }
        }

        public void validateAddPublisherAssertions(EntityManager em, AddPublisherAssertions body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<org.uddi.api_v3.PublisherAssertion> entityList = body.getPublisherAssertion();
                if (entityList == null || entityList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.addpublisherassertions.NoInput"));
                }

                for (org.uddi.api_v3.PublisherAssertion entity : entityList) {
                        validatePublisherAssertion(em, entity);
                }
        }

        public void validateSetPublisherAssertions(EntityManager em, Holder<List<org.uddi.api_v3.PublisherAssertion>> body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // Assertion list can be null or empty - it signifies that publisher is deleting all their assertions
                List<org.uddi.api_v3.PublisherAssertion> entityList = body.value;
                if (entityList != null && entityList.size() > 0) {

                        for (org.uddi.api_v3.PublisherAssertion entity : entityList) {
                                validatePublisherAssertion(em, entity);
                        }
                }
        }

        void validateNotSigned(org.uddi.api_v3.BusinessEntity item) throws ValueNotAllowedException {
                if (item == null) {
                        return;
                }
                if (item.getBusinessKey() == null && !item.getSignature().isEmpty()) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "businessKey"));
                }
                if (item.getBusinessServices() != null && !item.getSignature().isEmpty()) {
                        for (int i = 0; i < item.getBusinessServices().getBusinessService().size(); i++) {
                                if (item.getBusinessServices().getBusinessService().get(i).getBusinessKey() == null
                                        || item.getBusinessServices().getBusinessService().get(i).getBusinessKey().length() == 0) {
                                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "business/Service(" + i + ")/businessKey"));
                                }
                                if (item.getBusinessServices().getBusinessService().get(i).getServiceKey() == null
                                        || item.getBusinessServices().getBusinessService().get(i).getServiceKey().length() == 0) {
                                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "business/Service(" + i + ")/serviceKey"));
                                }
                                if (item.getBusinessServices().getBusinessService().get(i).getBindingTemplates() != null) {
                                        for (int k = 0; k < item.getBusinessServices().getBusinessService().get(i).getBindingTemplates().getBindingTemplate().size(); k++) {
                                                if (item.getBusinessServices().getBusinessService().get(i).getBindingTemplates().getBindingTemplate().get(k).getBindingKey() == null
                                                        || item.getBusinessServices().getBusinessService().get(i).getBindingTemplates().getBindingTemplate().get(k).getBindingKey().length() == 0) {
                                                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "business/Service(" + i + ")/bindingTemplate)" + k + ")/bindingKey"));
                                                }
                                        }
                                }
                        }
                }
        }

        void validateNotSigned(org.uddi.api_v3.BindingTemplate item) throws ValueNotAllowedException {
                if (item == null) {
                        return;
                }
                if (item.getBindingKey() == null && !item.getSignature().isEmpty()) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "bindingKey"));
                }
                if (item.getServiceKey() == null && !item.getSignature().isEmpty()) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "serviceKey"));
                }
        }

        void validateNotSigned(org.uddi.api_v3.TModel item) throws ValueNotAllowedException {
                if (item == null) {
                        return;
                }
                if (item.getTModelKey() == null && !item.getSignature().isEmpty()) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "tModelKey"));
                }
        }

        void validateNotSigned(org.uddi.api_v3.BusinessService item) throws ValueNotAllowedException {
                if (item == null) {
                        return;
                }
                if (item.getBusinessKey() == null && !item.getSignature().isEmpty()) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "businessKey"));
                }
                if (item.getServiceKey() == null && !item.getSignature().isEmpty()) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "serviceKey"));
                }
                //if i'm signed and a key isn't defined in a bt
                if (item.getBindingTemplates() != null && !item.getSignature().isEmpty()) {
                        for (int i = 0; i < item.getBindingTemplates().getBindingTemplate().size(); i++) {
                                if (item.getBindingTemplates().getBindingTemplate().get(i).getBindingKey() == null
                                        || item.getBindingTemplates().getBindingTemplate().get(i).getBindingKey().length() == 0) {
                                        throw new ValueNotAllowedException(new ErrorMessage("errors.entity.SignedButNoKey", "businessService/bindingTemplate(" + i + ")/bindingKey"));
                                }
                        }
                }
        }

        public void validateBusinessEntity(EntityManager em, org.uddi.api_v3.BusinessEntity businessEntity,
                Configuration config, UddiEntityPublisher publisher) throws DispositionReportFaultMessage {

                // A supplied businessEntity can't be null
                if (businessEntity == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.businessentity.NullInput"));
                }

                boolean entityExists = false;
                validateNotSigned(businessEntity);
                String entityKey = businessEntity.getBusinessKey();
                if (entityKey == null || entityKey.length() == 0) {
                        KeyGenerator keyGen = KeyGeneratorFactory.getKeyGenerator();
                        entityKey = keyGen.generate(publisher);
                        businessEntity.setBusinessKey(entityKey);
                } else {
                        // Per section 4.4: keys must be case-folded
                        entityKey = entityKey.toLowerCase();
                        businessEntity.setBusinessKey(entityKey);
                        validateKeyLength(entityKey);
                        Object obj = em.find(org.apache.juddi.model.BusinessEntity.class, entityKey);
                        if (obj != null) {
                                entityExists = true;

                                // Make sure publisher owns this entity.
                                AccessCheck(obj, entityKey);

                        } else {
                                // Inside this block, we have a key proposed by the publisher on a new entity

                                // Validate key and then check to see that the proposed key is valid for this publisher
                                ValidateUDDIKey.validateUDDIv3Key(entityKey);
                                if (!publisher.isValidPublisherKey(em, entityKey)) {
                                        throw new KeyUnavailableException(new ErrorMessage("errors.keyunavailable.BadPartition", entityKey));
                                }

                        }
                }

                if (!entityExists) {
                        // Check to make sure key isn't used by another entity.
                        if (!isUniqueKey(em, entityKey)) {
                                throw new KeyUnavailableException(new ErrorMessage("errors.keyunavailable.KeyExists", entityKey));
                        }
                }

                // was TODO: validate "checked" categories or category groups (see section 5.2.3 of spec)? optional to support
                //covered by ref integrity checks
                validateNames(businessEntity.getName());
                validateDiscoveryUrls(businessEntity.getDiscoveryURLs());
                validateContacts(businessEntity.getContacts(), config);
                validateCategoryBag(businessEntity.getCategoryBag(), config, false);
                validateIdentifierBag(businessEntity.getIdentifierBag(), config, false);
                validateDescriptions(businessEntity.getDescription());
                validateBusinessServices(em, businessEntity.getBusinessServices(), businessEntity, config, publisher);
                validateSignaturesBusiness(businessEntity, config);

        }

        public void validateBusinessServices(EntityManager em, org.uddi.api_v3.BusinessServices businessServices,
                org.uddi.api_v3.BusinessEntity parent, Configuration config, UddiEntityPublisher publisher)
                throws DispositionReportFaultMessage {
                // Business services is optional
                if (businessServices == null) {
                        return;
                }
                List<org.uddi.api_v3.BusinessService> businessServiceList = businessServices.getBusinessService();
                if (businessServiceList == null || businessServiceList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.businessservices.NoInput"));
                }

                for (org.uddi.api_v3.BusinessService businessService : businessServiceList) {
                        validateBusinessService(em, businessService, parent, config, publisher);
                }

        }

        public void validateBusinessService(EntityManager em, org.uddi.api_v3.BusinessService businessService,
                org.uddi.api_v3.BusinessEntity parent, Configuration config, UddiEntityPublisher publisher)
                throws DispositionReportFaultMessage {

                // A supplied businessService can't be null
                if (businessService == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.businessservice.NullInput"));
                }

                validateNotSigned(businessService);
                // Retrieve the service's passed key
                String entityKey = businessService.getServiceKey();
                if (entityKey != null && entityKey.length() > 0) {
                        // Per section 4.4: keys must be case-folded
                        entityKey = entityKey.toLowerCase();
                        validateKeyLength(entityKey);
                        businessService.setServiceKey(entityKey);
                }

                // The parent key is either supplied or provided by the higher call to the parent entity save.  If the passed-in parent's business key differs from 
                // the (non-null) business key retrieved from the service, then we have a possible service projection.
                String parentKey = businessService.getBusinessKey();
                if (parentKey != null && parentKey.length() > 0) {
                        // Per section 4.4: keys must be case-folded
                        parentKey = parentKey.toLowerCase();
                        businessService.setBusinessKey(parentKey);
                }

                boolean isProjection = false;
                if (parent != null) {
                        if (parentKey != null && parentKey.length() > 0) {
                                if (!parentKey.equalsIgnoreCase(parent.getBusinessKey())) {
                                        // Possible projected service - if we have differing parent businesses but a service key was not provided, this is an error as it is not possible 
                                        // for the business that doesn't "own" the service to generate the key for it.
                                        if (entityKey == null || entityKey.length() == 0) {
                                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.ServiceKeyNotProvidedWithProjection", parentKey + ", " + parent.getBusinessKey()));
                                        }

                                        isProjection = true;
                                }
                        } else {
                                parentKey = parent.getBusinessKey();
                        }
                }

                // Projections don't require as rigorous testing as only the projected service's business key and service key are examined for validity.
                if (isProjection) {

                        Object obj = em.find(org.apache.juddi.model.BusinessService.class, entityKey);
                        // Can't project a service that doesn't exist!
                        if (obj == null) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.ProjectedServiceNotFound", parentKey + ", " + entityKey));
                        } else {
                                // If the supplied business key doesn't match the existing service's business key, the projection is invalid.
                                org.apache.juddi.model.BusinessService bs = (org.apache.juddi.model.BusinessService) obj;
                                if (!businessService.getBusinessKey().equalsIgnoreCase(bs.getBusinessEntity().getEntityKey())) {
                                        throw new InvalidProjectionException(new ErrorMessage("errors.invalidprojection.ParentMismatch", businessService.getBusinessKey() + ", " + bs.getBusinessEntity().getEntityKey()));
                                }
                        }
                        obj = null;
                } else {
                        boolean entityExists = false;
                        if (entityKey == null || entityKey.length() == 0) {
                                KeyGenerator keyGen = KeyGeneratorFactory.getKeyGenerator();
                                entityKey = keyGen.generate(publisher);
                                businessService.setServiceKey(entityKey);
                        } else {

                                Object obj = em.find(org.apache.juddi.model.BusinessService.class, entityKey);
                                if (obj != null) {
                                        entityExists = true;

                                        org.apache.juddi.model.BusinessService bs = (org.apache.juddi.model.BusinessService) obj;

                                        // If the object exists, and the parentKey was not found to this point, then a save on an existing service with a blank
                                        // business key has occurred.  It is set here and added to the entity being saved - a necessary step for the object to be
                                        // persisted properly. (This condition makes some validation tests below unnecessary as the parent is "verified" but it's OK to
                                        // still run them).
                                        if (parentKey == null || parentKey.length() == 0) {
                                                parentKey = bs.getBusinessEntity().getEntityKey();
                                                businessService.setBusinessKey(parentKey);
                                        }

                                        // Make sure publisher owns this entity.
                                        AccessCheck(obj, entityKey);

                                        // If existing service trying to be saved has a different parent key, then we have a problem
                                        if (!parentKey.equalsIgnoreCase(bs.getBusinessEntity().getEntityKey())) {
                                                // if both businesses are owned by this publisher then we allow it.
                                                // we already check the current business is owned, lets see if the old one is too
                                                if (!publisher.isOwner(bs.getBusinessEntity())) {
                                                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.businessservice.ParentMismatch", parentKey + ", " + bs.getBusinessEntity().getEntityKey()));
                                                } else {
                                                        if (log.isDebugEnabled()) {
                                                                log.debug("Services moved from business " + bs.getBusinessEntity() + " to " + businessService.getBusinessKey());
                                                        }
                                                }
                                        }

                                } else {
                                        // Inside this block, we have a key proposed by the publisher on a new entity

                                        // Validate key and then check to see that the proposed key is valid for this publisher
                                        ValidateUDDIKey.validateUDDIv3Key(entityKey);
                                        if (!publisher.isValidPublisherKey(em, entityKey)) {
                                                throw new KeyUnavailableException(new ErrorMessage("errors.keyunavailable.BadPartition", entityKey));
                                        }

                                }

                        }

                        // Parent key must be passed if this is a new entity
                        if (!entityExists) {
                                if (parentKey == null || parentKey.length() == 0) {
                                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.ParentBusinessNotFound", parentKey));
                                }
                        }

                        // If parent key IS passed, whether new entity or not, it must be valid.  Additionally, the current publisher must be the owner of the parent.  Note that
                        // if a parent ENTITY was passed in, then we don't need to check for any of this since this is part of a higher call.
                        if (parentKey != null) {
                                if (parent == null) {
                                        Object parentTemp = em.find(org.apache.juddi.model.BusinessEntity.class, parentKey);
                                        if (parentTemp == null) {
                                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.ParentBusinessNotFound", parentKey));
                                        }

                                        // Make sure publisher owns this parent entity.
                                        AccessCheck(parentTemp, parentKey);
                                        // if (!publisher.isOwner((UddiEntity) parentTemp)) {
                                        //        throw new UserMismatchException(new ErrorMessage("errors.usermismatch.InvalidOwnerParent", parentKey));
                                        //}
                                }
                        }

                        if (!entityExists) {
                                // Check to make sure key isn't used by another entity.
                                if (!isUniqueKey(em, entityKey)) {
                                        throw new KeyUnavailableException(new ErrorMessage("errors.keyunavailable.KeyExists", entityKey));
                                }
                        }

                        // TODO: validate "checked" categories or category groups (see section 5.2.3 of spec)? optional to support
                        validateNames(businessService.getName());
                        validateCategoryBag(businessService.getCategoryBag(), config, false);
                        validateDescriptions(businessService.getDescription());
                        validateBindingTemplates(em, businessService.getBindingTemplates(), businessService, config, publisher);
                        validateSignaturesService(businessService, config);
                }

        }

        public void validateBindingTemplates(EntityManager em, org.uddi.api_v3.BindingTemplates bindingTemplates,
                org.uddi.api_v3.BusinessService parent, Configuration config, UddiEntityPublisher publisher)
                throws DispositionReportFaultMessage {
                // Binding templates is optional
                if (bindingTemplates == null) {
                        return;
                }

                List<org.uddi.api_v3.BindingTemplate> bindingTemplateList = bindingTemplates.getBindingTemplate();
                if (bindingTemplateList == null || bindingTemplateList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.bindingtemplates.NoInput"));
                }

                for (org.uddi.api_v3.BindingTemplate bindingTemplate : bindingTemplateList) {
                        validateBindingTemplate(em, bindingTemplate, parent, config, publisher);
                }

        }

        public void validateBindingTemplate(EntityManager em, org.uddi.api_v3.BindingTemplate bindingTemplate,
                org.uddi.api_v3.BusinessService parent, Configuration config, UddiEntityPublisher publisher)
                throws DispositionReportFaultMessage {

                // A supplied bindingTemplate can't be null
                if (bindingTemplate == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.bindingtemplate.NullInput"));
                }

                // Retrieve the binding's passed key
                String entityKey = bindingTemplate.getBindingKey();
                if (entityKey != null && entityKey.length() > 0) {
                        // Per section 4.4: keys must be case-folded
                        entityKey = entityKey.toLowerCase();
                        bindingTemplate.setBindingKey(entityKey);
                        validateKeyLength(entityKey);
                }

                // The parent key is either supplied or provided by the higher call to the parent entity save.  If it is provided in both instances, if they differ, an 
                // error occurs.
                String parentKey = bindingTemplate.getServiceKey();
                if (parentKey != null && parentKey.length() > 0) {
                        // Per section 4.4: keys must be case-folded
                        parentKey = parentKey.toLowerCase();
                        bindingTemplate.setServiceKey(parentKey);
                }

                if (parent != null) {
                        if (parentKey != null && parentKey.length() > 0) {
                                if (!parentKey.equalsIgnoreCase(parent.getServiceKey())) {
                                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.bindingtemplate.ParentMismatch", parentKey + ", " + parent.getBusinessKey()));
                                }
                        } else {
                                parentKey = parent.getServiceKey();
                        }
                }

                boolean entityExists = false;
                if (entityKey == null || entityKey.length() == 0) {
                        validateNotSigned(bindingTemplate);
                        KeyGenerator keyGen = KeyGeneratorFactory.getKeyGenerator();
                        entityKey = keyGen.generate(publisher);
                        bindingTemplate.setBindingKey(entityKey);
                } else {

                        Object obj = em.find(org.apache.juddi.model.BindingTemplate.class, entityKey);
                        if (obj != null) {
                                entityExists = true;

                                org.apache.juddi.model.BindingTemplate bt = (org.apache.juddi.model.BindingTemplate) obj;

                                // If the object exists, and the parentKey was not found to this point, then a save on an existing binding with a blank
                                // service key has occurred.  It is set here and added to the entity being saved - a necessary step for the object to be
                                // persisted properly. (This condition makes some validation tests below unnecessary as the parent is "verified" but it's OK to
                                // still run them).
                                if (parentKey == null || parentKey.length() == 0) {
                                        parentKey = bt.getBusinessService().getEntityKey();
                                        bindingTemplate.setServiceKey(parentKey);
                                }

                                // If existing binding trying to be saved has a different parent key, then we have a problem
                                // TODO: moving bindings is allowed according to spec?
                                if (!parentKey.equalsIgnoreCase(bt.getBusinessService().getEntityKey())) {
                                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.bindingtemplate.ParentMismatch", parentKey + ", " + bt.getBusinessService().getEntityKey()));
                                }

                                // Make sure publisher owns this entity.
                                AccessCheck(obj, entityKey);
                                //if (!publisher.isOwner((UddiEntity) obj)&& !((Publisher) publisher).isAdmin()) {
//                                        throw new UserMismatchException(new ErrorMessage("errors.usermismatch.InvalidOwner", entityKey));
                                //                              }

                        } else {
                                // Inside this block, we have a key proposed by the publisher on a new entity

                                // Validate key and then check to see that the proposed key is valid for this publisher
                                ValidateUDDIKey.validateUDDIv3Key(entityKey);
                                if (!publisher.isValidPublisherKey(em, entityKey)) {
                                        throw new KeyUnavailableException(new ErrorMessage("errors.keyunavailable.BadPartition", entityKey));
                                }

                        }

                }

                // Parent key must be passed if this is a new entity
                if (!entityExists) {
                        if (parentKey == null || parentKey.length() == 0) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.ParentServiceNotFound", parentKey));
                        }
                }

                // If parent key IS passed, whether new entity or not, it must be valid.  Additionally, the current publisher must be the owner of the parent.  Note that
                // if a parent ENTITY was passed in, then we don't need to check for any of this since this is part of a higher call.
                if (parentKey != null) {
                        if (parent == null) {
                                Object parentTemp = em.find(org.apache.juddi.model.BusinessService.class, parentKey);
                                if (parentTemp == null) {
                                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.ParentBusinessNotFound", parentKey));
                                } else if (!(parentTemp instanceof org.apache.juddi.model.BusinessService)) {
                                        //JUDDI-848
                                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.ParentBusinessNotFound", parentKey));
                                }

                                // Make sure publisher owns this parent entity.
                                AccessCheck(parentTemp, parentKey);
//                                if (!publisher.isOwner((UddiEntity) parentTemp)) {
//                                        throw new UserMismatchException(new ErrorMessage("errors.usermismatch.InvalidOwnerParent", parentKey));
//                                }

                        }
                }

                if (!entityExists) {
                        // Check to make sure key isn't used by another entity.
                        if (!isUniqueKey(em, entityKey)) {
                                throw new KeyUnavailableException(new ErrorMessage("errors.keyunavailable.KeyExists", entityKey));
                        }
                }

                //was TODO validate "checked" categories or category groups (see section 5.2.3 of spec)? optional to support
                //at least one must be defined
                if (bindingTemplate.getAccessPoint() == null && bindingTemplate.getHostingRedirector() == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.bindingtemplate.NoAccessPoint"));
                }
                //but not both
                if (bindingTemplate.getAccessPoint() != null && bindingTemplate.getHostingRedirector() != null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.bindingtemplate.NoAccessPoint"));
                }
                validateCategoryBag(bindingTemplate.getCategoryBag(), config, false);
                validateTModelInstanceDetails(bindingTemplate.getTModelInstanceDetails(), config, false);
                validateAccessPoint(em, bindingTemplate.getAccessPoint(), config);
                validateDescriptions(bindingTemplate.getDescription());
                validateHostingRedirector(em, bindingTemplate.getHostingRedirector(), config);

                validateSignaturesBinding(bindingTemplate, config);
                //validateCheckedTModels(bindingTemplate, config);
        }

        public void validateTModel(EntityManager em, org.uddi.api_v3.TModel tModel, Configuration config, UddiEntityPublisher publisher) throws DispositionReportFaultMessage {
                // A supplied tModel can't be null
                if (tModel == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.tmodel.NullInput"));
                }

                boolean entityExists = false;
                String entityKey = tModel.getTModelKey();
                if (entityKey == null || entityKey.length() == 0) {
                        KeyGenerator keyGen = KeyGeneratorFactory.getKeyGenerator();
                        entityKey = keyGen.generate(publisher);
                        validateNotSigned(tModel);
                        tModel.setTModelKey(entityKey);
                } else {
                        // Per section 4.4: keys must be case-folded
                        entityKey = entityKey.toLowerCase();
                        tModel.setTModelKey(entityKey);

                        Object obj = em.find(org.apache.juddi.model.Tmodel.class, entityKey);
                        if (obj != null) {
                                entityExists = true;

                                // Make sure publisher owns this entity.
                                AccessCheck(obj, entityKey);
                                //if (!publisher.isOwner((UddiEntity) obj)&& !((Publisher) publisher).isAdmin()) {
                                //        throw new UserMismatchException(new ErrorMessage("errors.usermismatch.InvalidOwner", entityKey));
                                // }
                        } else {
                                // Inside this block, we have a key proposed by the publisher on a new entity

                                // First test to see if this is a Key Generator tModel. The keyGenerator suffix appearing in the key is the indicator, since this is not
                                // allowed *unless* it's a key generator.
                                if (entityKey.toUpperCase().contains(KeyGenerator.KEYGENERATOR_SUFFIX.toUpperCase())) {
                                        ValidateUDDIKey.validateUDDIv3KeyGeneratorTModel(tModel);

                                        // The root publisher is only allowed one key generator.  This is published in the installation.
                                        String rootPublisherStr = "root";
                                        try {
                                                rootPublisherStr = AppConfig.getConfiguration().getString(Property.JUDDI_ROOT_PUBLISHER);
                                        } catch (ConfigurationException ce) {
                                                log.error("Could not read the root publisher setting in the configuration.");
                                        }
                                        if (publisher.getAuthorizedName().equals(rootPublisherStr)) {
                                                throw new FatalErrorException(new ErrorMessage("errors.tmodel.keygenerator.RootKeyGen"));
                                        }

                                        // It's a valid Key Generator, but is it available for this publisher?
                                        if (!publisher.isKeyGeneratorAvailable(em, entityKey)) {
                                                throw new KeyUnavailableException(new ErrorMessage("errors.keyunavailable.BadPartition", entityKey));
                                        }

                                } else {
                                        // If not a key generator, then simply validate key and then check to see that the proposed key is valid for this publisher
                                        ValidateUDDIKey.validateUDDIv3Key(entityKey);
                                        //fix for JUDDI-851
                                        if (!entityKey.toUpperCase().startsWith("UUID:")) {
                                                if (!publisher.isValidPublisherKey(em, entityKey)) {
                                                        throw new KeyUnavailableException(new ErrorMessage("errors.keyunavailable.BadPartition", entityKey));
                                                }
                                        }
                                }
                        }
                }

                if (!entityExists) {
                        // Check to make sure key isn't used by another entity.
                        if (!isUniqueKey(em, entityKey)) {
                                throw new KeyUnavailableException(new ErrorMessage("errors.keyunavailable.KeyExists", entityKey));
                        }
                }
                validateKeyLength(entityKey);

                // TODO: validate "checked" categories or category groups (see section 5.2.3 of spec)? optional to support
                if (tModel.getName() == null || tModel.getName().getValue() == null
                        || tModel.getName().getValue().equals("")) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.tmodel.NoName"));
                }

                validateCategoryBag(tModel.getCategoryBag(), config, false);
                validateIdentifierBag(tModel.getIdentifierBag(), config, false);
                validateDescriptions(tModel.getDescription());
                validateNameLength(tModel.getName().getValue());
                validateLang(tModel.getName().getLang());
                List<org.uddi.api_v3.OverviewDoc> overviewDocList = tModel.getOverviewDoc();
                if (overviewDocList != null) {
                        for (org.uddi.api_v3.OverviewDoc overviewDoc : overviewDocList) {
                                validateOverviewDoc(overviewDoc);
                        }
                }
                validateSignaturesTModel(tModel, config);

        }

        public void validatePublisherAssertion(EntityManager em, org.uddi.api_v3.PublisherAssertion pubAssertion) throws DispositionReportFaultMessage {
                // A supplied publisher assertion can't be null
                if (pubAssertion == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.pubassertion.NullInput"));
                }

                // The keyedRef must not be blank and every field must contain data.
                org.uddi.api_v3.KeyedReference keyedRef = pubAssertion.getKeyedReference();
                if (keyedRef == null
                        || keyedRef.getTModelKey() == null || keyedRef.getTModelKey().length() == 0
                        || keyedRef.getKeyName() == null || keyedRef.getKeyName().length() == 0
                        || keyedRef.getKeyValue() == null || keyedRef.getKeyValue().length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.pubassertion.BlankKeyedRef"));
                }

                String fromKey = pubAssertion.getFromKey();
                if (fromKey == null || fromKey.length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.pubassertion.BlankFromKey"));
                }

                String toKey = pubAssertion.getToKey();
                if (toKey == null || toKey.length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.pubassertion.BlankToKey"));
                }

                if (fromKey.equalsIgnoreCase(toKey)) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.pubassertion.SameBusinessKey"));
                }

                // Per section 4.4: keys must be case-folded
                fromKey = fromKey.toLowerCase();
                pubAssertion.setFromKey(fromKey);
                toKey = toKey.toLowerCase();
                pubAssertion.setToKey(toKey);
                validateKeyLength(toKey);
                validateKeyLength(fromKey);
                Object fromObj = em.find(org.apache.juddi.model.BusinessEntity.class, fromKey);
                if (fromObj == null) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.BusinessNotFound", fromKey));
                }

                Object toObj = em.find(org.apache.juddi.model.BusinessEntity.class, pubAssertion.getToKey());
                if (toObj == null) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.BusinessNotFound", toKey));
                }

                if (!publisher.isOwner((UddiEntity) fromObj) && !publisher.isOwner((UddiEntity) toObj)) {
                        throw new UserMismatchException(new ErrorMessage("errors.pubassertion.UserMismatch", fromKey + " & " + toKey));
                }

                try {
                        validateKeyedReference(pubAssertion.getKeyedReference(), AppConfig.getConfiguration(), false);
                } catch (ConfigurationException ce) {
                        log.error("Could not optain config. " + ce.getMessage(), ce);
                }
        }

        public void validateNames(List<org.uddi.api_v3.Name> names) throws DispositionReportFaultMessage {
                // At least one name is required
                if (names == null || names.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.names.NoInput"));
                }

                for (Name n : names) {
                        if (n.getValue() == null || n.getValue().length() == 0) {
                                throw new ValueNotAllowedException(new ErrorMessage("errors.names.NoValue"));
                        }
                        validateNameLength(n.getValue());
                        validateLang(n.getLang());
                }

        }

        public void validateContacts(org.uddi.api_v3.Contacts contacts, Configuration config) throws DispositionReportFaultMessage {
                // Contacts is optional
                if (contacts == null) {
                        return;
                }

                // If contacts do exist, at least one contact is required
                List<org.uddi.api_v3.Contact> contactList = contacts.getContact();
                if (contactList == null || contactList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.contacts.NoInput"));
                }

                for (org.uddi.api_v3.Contact contact : contactList) {
                        validateContact(contact, config);
                }

        }

        public void validateContact(org.uddi.api_v3.Contact contact, Configuration config) throws DispositionReportFaultMessage {
                if (log.isDebugEnabled()) {
                        log.debug("validateContact");
                }
                // A supplied contact can't be null
                if (contact == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.contact.NullInput"));
                }

                // At least one personName is required
                List<org.uddi.api_v3.PersonName> pnameList = contact.getPersonName();
                if (pnameList == null || pnameList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.contact.NoPersonName"));
                }
                for (org.uddi.api_v3.PersonName pn : pnameList) {
                        if (pn.getValue() == null || pn.getValue().length() == 0) {
                                throw new ValueNotAllowedException(new ErrorMessage("errors.contacts.NoPersonName"));
                        }
                        validateNameLength(pn.getValue());
                        validateLang(pn.getLang());
                }

                List<org.uddi.api_v3.Address> addressList = contact.getAddress();
                if (addressList != null) {
                        for (org.uddi.api_v3.Address address : addressList) {
                                if (address != null) {
                                        validateSortCode(address.getSortCode());
                                        validateKeyLength(address.getTModelKey());
                                        validateLang(address.getLang());
                                        validateUseType(address.getUseType());
                                        boolean checked = true;
                                        // Per section 4.4: keys must be case-folded
                                        if (address.getTModelKey() != null) {
                                                address.setTModelKey(address.getTModelKey().toLowerCase());
                                                validatedAddressLinesIfKeyDefined(address.getAddressLine());

                                                checked = verifyTModelKeyExistsAndChecked(address.getTModelKey(), config);

                                        }
                                        if (address.getAddressLine() == null || address.getAddressLine().size() == 0) {
                                                throw new ValueNotAllowedException(new ErrorMessage("errors.contact.NoAddressLine"));
                                        }

                                        if (checked) {
                                                validateAddressLines(address.getAddressLine(), config);
                                        }
                                }
                        }
                }
                validateEmailAddress(contact.getEmail());
                validatePhone(contact.getPhone());
                validateDescriptions(contact.getDescription());
                validateUseType(contact.getUseType());
        }

        public void validateDiscoveryUrls(org.uddi.api_v3.DiscoveryURLs discUrls) throws DispositionReportFaultMessage {
                // Discovery Urls is optional
                if (discUrls == null) {
                        return;
                }

                // If discUrls does exist, it must have at least one element
                List<org.uddi.api_v3.DiscoveryURL> discUrlList = discUrls.getDiscoveryURL();
                if (discUrlList == null || discUrlList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.discurls.NoInput"));
                }
                for (org.uddi.api_v3.DiscoveryURL url : discUrlList) {
                        if (url.getValue() == null || url.getValue().length() == 0) {
                                throw new ValueNotAllowedException(new ErrorMessage("errors.discurls.NoInput"));
                        }
                        validateDiscoveryUrlLength(url);
                }
        }

        public void validateCategoryBag(org.uddi.api_v3.CategoryBag categories, Configuration config, boolean isRoot) throws DispositionReportFaultMessage {

                // Category bag is optional
                if (categories == null) {
                        return;
                }

                // If category bag does exist, it must have at least one element
                List<KeyedReference> elems = categories.getKeyedReference();
                List<KeyedReferenceGroup> groups = categories.getKeyedReferenceGroup();
                if (groups.size() == 0 && elems.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.categorybag.NoInput"));
                }

                for (KeyedReferenceGroup group : groups) {
                        validateKeyedReferenceGroup(group, config, isRoot);
                }

                for (KeyedReference elem : elems) {
                        validateKeyedReference(elem, config, isRoot);
                }
        }

        public void validateIdentifierBag(org.uddi.api_v3.IdentifierBag identifiers, Configuration config, boolean isRoot) throws DispositionReportFaultMessage {

                // Identifier bag is optional
                if (identifiers == null) {
                        return;
                }

                // If category bag does exist, it must have at least one element
                List<org.uddi.api_v3.KeyedReference> keyedRefList = identifiers.getKeyedReference();
                if (keyedRefList == null || keyedRefList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.identifierbag.NoInput"));
                }

                for (org.uddi.api_v3.KeyedReference keyedRef : keyedRefList) {
                        validateKeyedReference(keyedRef, config, isRoot);
                }
        }

        public void validateKeyedReferenceGroup(KeyedReferenceGroup krg, Configuration config, boolean isRoot) throws DispositionReportFaultMessage {
                // Keyed reference groups must contain a tModelKey
                if (log.isDebugEnabled()) {
                        log.debug("validateKeyedReferenceGroup");
                }
                if (krg.getTModelKey() == null || krg.getTModelKey().length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.keyedreference.NoTModelKey"));
                }

                // Per section 4.4: keys must be case-folded
                String tmodelKey = krg.getTModelKey().toLowerCase();
                krg.setTModelKey(tmodelKey);
                validateKeyLength(tmodelKey);

                boolean checkRef = false;
                try {
                        checkRef = config.getBoolean(Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY, false);
                } catch (Exception ex) {
                        log.warn("Error caught reading " + Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY + " from config file", ex);
                }
                if (checkRef && !isRoot) {
                        this.verifyTModelKeyExists(tmodelKey);
                }

                boolean checked = verifyTModelKeyExistsAndChecked(tmodelKey, config);

                if (checked) {
                        List<KeyedReference> keyedRefs = krg.getKeyedReference();
                        // Should being empty raise an error?
                        if (keyedRefs != null && keyedRefs.size() > 0) {
                                for (KeyedReference keyedRef : keyedRefs) {
                                        validateKeyedReference(keyedRef, config, isRoot);
                                }
                        }
                }
        }

        /**
         *
         * @param kr
         * @param config
         * @param isRoot true during install time, otherwise false
         * @throws DispositionReportFaultMessage
         */
        public void validateKeyedReference(KeyedReference kr, Configuration config, boolean isRoot) throws DispositionReportFaultMessage {
                if (log.isDebugEnabled()) {
                        log.debug("validateKeyedReference");
                }
                String tmodelKey = kr.getTModelKey();

                if (tmodelKey == null || tmodelKey.length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.keyedreference.NoTModelKey"));
                }

                // Per section 4.4: keys must be case-folded
                tmodelKey = tmodelKey.toLowerCase();
                kr.setTModelKey(tmodelKey);
                validateKeyLength(tmodelKey);

                if (kr.getKeyValue() == null || kr.getKeyValue().length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.keyedreference.NoKeyValue"));
                }
                validateKeyValue(kr.getKeyValue());
                validateKeyName(kr.getKeyName());

                boolean checkRef = false;
                try {
                        checkRef = config.getBoolean(Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY, false);
                } catch (Exception ex) {
                        log.warn("Error caught reading " + Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY + " from config file", ex);
                }
                if (checkRef && !isRoot) {
                        this.verifyTModelKeyExists(tmodelKey);

                }

                String rootPublisherStr = config.getString(Property.JUDDI_ROOT_PUBLISHER);
                // Per section 6.2.2.1 of the specification, no publishers (except the root) are allowed to use the node categorization tmodelKey
                if (Constants.NODE_CATEGORY_TMODEL.equalsIgnoreCase(kr.getTModelKey())) {
                        if (!rootPublisherStr.equals(publisher.getAuthorizedName())) {
                                throw new ValueNotAllowedException(new ErrorMessage("errors.keyedreference.NodeCategoryTModel", Constants.NODE_CATEGORY_TMODEL));
                        }
                }
        }

        public void validateTModelInstanceDetails(org.uddi.api_v3.TModelInstanceDetails tmodelInstDetails, Configuration config, boolean isRoot) throws DispositionReportFaultMessage {
                if (log.isDebugEnabled()) {
                        log.debug("validateTModelInstanceDetails");
                }
                // tModel Instance Details is optional
                if (tmodelInstDetails == null) {
                        return;
                }

                // If tmodelInstDetails does exist, it must have at least one element
                List<org.uddi.api_v3.TModelInstanceInfo> tmodelInstInfoList = tmodelInstDetails.getTModelInstanceInfo();
                if (tmodelInstInfoList == null || tmodelInstInfoList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.tmodelinstdetails.NoInput"));
                }

                for (org.uddi.api_v3.TModelInstanceInfo tmodelInstInfo : tmodelInstInfoList) {
                        validateTModelInstanceInfo(tmodelInstInfo, config, isRoot);
                }
        }

        public void validateTModelInstanceInfo(org.uddi.api_v3.TModelInstanceInfo tmodelInstInfo, Configuration config, boolean isRoot) throws DispositionReportFaultMessage {
                // tModel Instance Info can't be null
                if (tmodelInstInfo == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.tmodelinstinfo.NullInput"));
                }

                // TModel key is required
                if (tmodelInstInfo.getTModelKey() == null || tmodelInstInfo.getTModelKey().length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.tmodelinstinfo.NoTModelKey"));
                }

                // Per section 4.4: keys must be case-folded
                tmodelInstInfo.setTModelKey((tmodelInstInfo.getTModelKey().toLowerCase()));

                boolean checkRef = false;
                try {
                        checkRef = config.getBoolean(Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY, false);
                } catch (Exception ex) {
                        log.warn("Error caught reading " + Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY + " from config file", ex);
                }
                if (checkRef && !isRoot) {
                        this.verifyTModelKeyExists(tmodelInstInfo.getTModelKey());
                }

                validateInstanceDetails(tmodelInstInfo.getInstanceDetails());
                if (log.isDebugEnabled()) {
                        log.debug("validateTModelInstanceInfo");
                }

                validateKeyLength(tmodelInstInfo.getTModelKey());
                validateDescriptions(tmodelInstInfo.getDescription());

        }

        public void validateInstanceDetails(org.uddi.api_v3.InstanceDetails instDetails) throws DispositionReportFaultMessage {
                // Instance Details is optional
                if (instDetails == null) {
                        return;
                }

                // At least one OverviewDoc or instanceParms must be supplied
                List<OverviewDoc> elems = instDetails.getOverviewDoc();
                if (instDetails.getInstanceParms() == null && elems.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.instdetails.NoOverviewOrParms"));
                }
                for (int i = 0; i < elems.size(); i++) {
                        validateDescriptions(elems.get(i).getDescription());
                        validateOverviewURL(elems.get(i).getOverviewURL());
                }
        }

        public void validateOverviewDoc(org.uddi.api_v3.OverviewDoc overviewDoc) throws DispositionReportFaultMessage {
                // OverviewDoc can't be null
                if (overviewDoc == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.overviewdoc.NullInput"));
                }

                // At least one description or overview URL must be supplied
                List<org.uddi.api_v3.Description> elems = overviewDoc.getDescription();
                if ((elems == null || elems.size() == 0) && overviewDoc.getOverviewURL() == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.overviewdoc.NoDescOrUrl"));
                }
                for (int i = 0; i < elems.size(); i++) {
                        validateLang(elems.get(i).getLang());
                        validateURL(elems.get(i).getValue());
                }
        }

        public void validateRegisteredInfo(org.uddi.api_v3.GetRegisteredInfo body) throws DispositionReportFaultMessage {
                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // infoSelection is required
                if (body.getInfoSelection() == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.getregisteredinfo.NoInfoSelection"));
                }

        }

        /**
         * Publishing API functions are specific to jUDDI. Requires
         * administrative privilege
         *
         * @param em
         * @param body
         * @throws DispositionReportFaultMessage
         */
        public void validateDeletePublisher(EntityManager em, DeletePublisher body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<String> entityKeyList = body.getPublisherId();
                if (entityKeyList == null || entityKeyList.size() == 0) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.NoKeys"));
                }

                if (!((Publisher) publisher).isAdmin()) {
                        throw new UserMismatchException(new ErrorMessage("errors.deletepublisher.AdminReqd"));
                }

                HashSet<String> dupCheck = new HashSet<String>();
                for (String entityKey : entityKeyList) {
                        validateKeyLength(entityKey);
                        boolean inserted = dupCheck.add(entityKey);
                        if (!inserted) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.DuplicateKey", entityKey));
                        }

                        Object obj = em.find(org.apache.juddi.model.Publisher.class, entityKey);
                        if (obj == null) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.PublisherNotFound", entityKey));
                        }

                }
        }

        public void validateSaveSubscriptionAdmin(EntityManager em, String publisherOrUsername, List<Subscription> subscriptions) throws DispositionReportFaultMessage {

                // No null input
                if (subscriptions == null || subscriptions.isEmpty()) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                if (!((Publisher) publisher).isAdmin()) {
                        throw new UserMismatchException(new ErrorMessage("errors.deletepublisher.AdminReqd"));
                }
                UddiEntityPublisher user = new UddiEntityPublisher(publisherOrUsername);
                ValidateSubscription vsub = new ValidateSubscription(user);
                for (int i = 0; i < subscriptions.size(); i++) {
                        vsub.validateSubscriptions(em, subscriptions, user);
                }
        }

        public void validateSavePublisher(EntityManager em, SavePublisher body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<org.apache.juddi.api_v3.Publisher> entityList = body.getPublisher();
                if (entityList == null || entityList.size() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.savepublisher.NoInput"));
                }

                if (!((Publisher) publisher).isAdmin()) {
                        throw new UserMismatchException(new ErrorMessage("errors.savepublisher.AdminReqd", publisher.getAuthorizedName()));
                }

                for (org.apache.juddi.api_v3.Publisher entity : entityList) {
                        validatePublisher(em, entity);
                }
        }

        public void validatePublisher(EntityManager em, org.apache.juddi.api_v3.Publisher publisher) throws DispositionReportFaultMessage {

                // No null input
                if (publisher == null) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.publisher.NullInput"));
                }

                String authorizedName = publisher.getAuthorizedName();
                if (authorizedName == null || authorizedName.length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.publisher.NoAuthorizedName"));
                }

                String publisherName = publisher.getPublisherName();
                if (publisherName == null || publisherName.length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.publisher.NoPublisherName"));
                }
//TODO identify JUDDI restrictions on publisher name
        }

        public void validateAdminDeleteTModel(EntityManager em, DeleteTModel body) throws DispositionReportFaultMessage {

                // No null input
                if (body == null) {
                        throw new FatalErrorException(new ErrorMessage("errors.NullInput"));
                }

                // No null or empty list
                List<String> entityKeyList = body.getTModelKey();
                if (entityKeyList == null || entityKeyList.size() == 0) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.NoKeys"));
                }

                if (!((Publisher) publisher).isAdmin()) {
                        throw new UserMismatchException(new ErrorMessage("errors.AdminReqd"));
                }

                HashSet<String> dupCheck = new HashSet<String>();
                for (String entityKey : entityKeyList) {
                        validateKeyLength(entityKey);
                        boolean inserted = dupCheck.add(entityKey);
                        if (!inserted) {
                                throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.DuplicateKey", entityKey));
                        }

                        //removed a check for checking if the entity exists which was moved to the juddi api class
                        //why? because we were looking up the same object twice in the database and its just not efficient
                }
        }
        ////////////////////////////////////////////////////////////////////
        ////////////////////////// begin validation code
        ////////////////////////////////////////////////////////////////////

        private static void validateDescription(String value) throws ValueNotAllowedException {
                if (value != null && value.length() > ValidationConstants.MAX_description) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.DescriptionTooLong"));
                }
        }

        public static void validateLang(String lang) throws ValueNotAllowedException {
                if (lang != null && lang.length() > ValidationConstants.MAX_xml_lang) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.names.LangTooLong"));
                }
        }

        private static void validateUseType(String useType) throws ValueNotAllowedException {
                if (useType != null && useType.length() > ValidationConstants.MAX_useType) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.names.UseTypeTooLong"));
                }
        }

        public static void validateKeyLength(String value) throws ValueNotAllowedException {
                if (value != null && value.length() > ValidationConstants.MAX_Key) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.keys.TooLong"));
                }
        }

        private void validateAccessPoint(EntityManager em, AccessPoint value, Configuration config) throws ValueNotAllowedException {
                if (log.isDebugEnabled()) {
                        log.debug("validateAccessPoint");
                }

                if (value != null) {
                        if (value.getValue().length() > ValidationConstants.MAX_accessPoint) {
                                throw new ValueNotAllowedException(new ErrorMessage("errors.accessPoint.TooLong"));
                        }

                        validateUseType(value.getUseType());
                        if (value.getUseType() != null) {
                                if (value.getUseType().equalsIgnoreCase(AccessPointType.BINDING_TEMPLATE.toString())) {
                                        //validate that the referenced binding key exists already
                                        Object obj = em.find(org.apache.juddi.model.BindingTemplate.class, value.getValue());
                                        if (obj == null) {
                                                throw new ValueNotAllowedException(new ErrorMessage("errors.accessPoint.bindingtemplateRedirect.keynotexist"));
                                        }

                                } else if (value.getUseType().equalsIgnoreCase(AccessPointType.HOSTING_REDIRECTOR.toString())) {
                                        try {
                                                //no validation necessary other than confirm that it's a URL
                                                new URL(value.getValue());
                                        } catch (MalformedURLException ex) {
                                                throw new ValueNotAllowedException(new ErrorMessage("errors.accessPoint.hostingRedirector.notaurl"));
                                        }
                                }
                                //TODO determine if additional validation is required.
                                //potentials, if its a wsdl deployment, is the Value a valid URI
                                //if endpoint, is it a valid URI?
                        }
                }
        }

        private void validateHostingRedirector(EntityManager em, HostingRedirector hostingRedirector, Configuration config) throws ValueNotAllowedException {
                if (log.isDebugEnabled()) {
                        log.debug("validateHostingRedirector");
                }
                if (hostingRedirector == null) {
                        return;
                }

                if (hostingRedirector.getBindingKey() == null || hostingRedirector.getBindingKey().length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.hostingredirector.noinput"));
                }
                if (hostingRedirector.getBindingKey().length() > ValidationConstants.MAX_Key) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.hostingredirector.TooLong"));
                }
                boolean checkRef = false;
                try {
                        checkRef = config.getBoolean(Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY, false);
                } catch (Exception ex) {
                        log.warn("Error caught reading " + Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY + " from config file", ex);
                }
                if (checkRef) {
                        //TODO check the spec to confirm this is logically correct
            /*Object obj = em.find(org.apache.juddi.model.BindingTemplate.class, hostingRedirector.getBindingKey());
                         if (obj == null) {
                         throw new ValueNotAllowedException(new ErrorMessage("errors.hostingredirector.keynotexist"));
                         }*/
                }

        }

        private void validateNameLength(String value) throws ValueNotAllowedException {
                if (value == null || value.length() == 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.names.NoInput"));
                }
                if (value.length() > ValidationConstants.MAX_name) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.names.TooLong"));
                }

        }

        private void validateSortCode(String value) throws ValueNotAllowedException {
                if (value != null && value.length() > ValidationConstants.MAX_sortCode) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.sortCode.TooLong"));
                }
        }

        private void validateAddressLines(List<AddressLine> addressLine, Configuration config) throws ValueNotAllowedException {
                if (log.isDebugEnabled()) {
                        log.debug("validateAddressLines");
                }
                if (addressLine != null) {
                        for (int i = 0; i < addressLine.size(); i++) {
                                validateKeyName(addressLine.get(i).getKeyName());
                                verifyTModelKeyExistsAndChecked(addressLine.get(i).getKeyName(), config);

                                validateKeyValue(addressLine.get(i).getKeyValue());
                                if (addressLine.get(i).getValue() == null || addressLine.get(i).getValue().length() == 0) {
                                        throw new ValueNotAllowedException(new ErrorMessage("errors.addressline.noinput"));
                                }
                                if (addressLine.get(i).getValue().length() > ValidationConstants.MAX_addressLine) {
                                        throw new ValueNotAllowedException(new ErrorMessage("errors.addressline.TooLong"));
                                }
                        }
                }
        }

        private void validateEmailAddress(List<Email> email) throws ValueNotAllowedException {
                if (email != null) {
                        for (int i = 0; i < email.size(); i++) {
                                validateUseType(email.get(i).getUseType());
                                if (email.get(i).getValue() == null || email.get(i).getValue().length() == 0) {
                                        throw new ValueNotAllowedException(new ErrorMessage("errors.email.noinput"));
                                }
                                if (email.get(i).getValue().length() > ValidationConstants.MAX_email) {
                                        throw new ValueNotAllowedException(new ErrorMessage("errors.email.TooLong"));
                                }
                        }
                }
        }

        private void validatePhone(List<Phone> phone) throws ValueNotAllowedException {
                if (phone != null) {
                        for (int i = 0; i < phone.size(); i++) {
                                validateUseType(phone.get(i).getUseType());
                                if (phone.get(i).getValue() == null
                                        || phone.get(i).getValue().length() == 0) {
                                        throw new ValueNotAllowedException(new ErrorMessage("errors.phone.noinput"));
                                }
                                if (phone.get(i).getValue().length() > ValidationConstants.MAX_phone) {
                                        throw new ValueNotAllowedException(new ErrorMessage("errors.phone.TooLong"));
                                }
                        }
                }
        }

        private void validateDiscoveryUrlLength(DiscoveryURL url) throws ValueNotAllowedException {
                if (url != null) {
                        validateUseType(url.getUseType());
                        validateURL(url.getValue());
                }
        }

        private void validateKeyValue(String value) throws ValueNotAllowedException {
                if (value != null && value.length() > ValidationConstants.MAX_keyValue) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.keyvalue.TooLong"));
                }
        }

        private void validateKeyName(String value) throws ValueNotAllowedException {
                if (value != null && value.length() > ValidationConstants.MAX_keyValue) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.keyname.TooLong"));
                }

        }

        private void validateDescriptions(List<Description> description) throws ValueNotAllowedException {
                for (int i = 0; i < description.size(); i++) {
                        if (description.get(i).getValue() == null) {
                                throw new ValueNotAllowedException(new ErrorMessage("errors.contact.EmptyDescription"));
                        }

                        validateLang(description.get(i).getLang());
                        validateDescription(description.get(i).getValue());
                }
        }

        private void validateOverviewURL(OverviewURL overviewURL) throws ValueNotAllowedException {
                if (overviewURL != null) {
                        validateUseType(overviewURL.getUseType());
                        validateURL(overviewURL.getValue());
                }
        }

        private void validateURL(String value) throws ValueNotAllowedException {
                if (value != null && value.length() > ValidationConstants.MAX_overviewURL) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.url.overviewTooLong"));
                }
        }

        /**
         * Validates that a tmodel key is registered Alex O'Ree
         *
         * @param tmodelKey
         * @param em
         * @throws ValueNotAllowedException
         * @see org.apache.juddi.config.Install
         * @since 3.1.5
         */
        private boolean verifyTModelKeyExistsAndChecked(String tmodelKey, Configuration config) throws ValueNotAllowedException {
                boolean checked = true;
                if (tmodelKey == null || tmodelKey.length() == 0) {
                        return false;
                }
                if (tmodelKey.equalsIgnoreCase("uddi:uddi.org:categorization:types")) {
                        return false;
                }
                if (tmodelKey.equalsIgnoreCase("uddi:uddi.org:categorization:nodes")) {
                        return false;
                }
                if (tmodelKey.equalsIgnoreCase("uddi:uddi.org:v3_inquiry")) {
                        return false;
                }
                if (tmodelKey.equalsIgnoreCase("uddi:uddi.org:v3_publication")) {
                        return false;
                }
                if (tmodelKey.equalsIgnoreCase("uddi:uddi.org:v3_security")) {
                        return false;
                }
                if (tmodelKey.equalsIgnoreCase("uddi:uddi.org:v3_ownership_transfer")) {
                        return false;
                }
                if (tmodelKey.equalsIgnoreCase("uddi:uddi.org:v3_subscription")) {
                        return false;
                }
                if (tmodelKey.equalsIgnoreCase("uddi:uddi.org:v3_subscriptionlistener")) {
                        return false;
                }

                if (config == null) {
                        log.warn(new ErrorMessage("errors.tmodel.ReferentialIntegrityNullConfig"));
                        return false;
                }
                boolean checkRef = false;
                try {
                        checkRef = config.getBoolean(Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY, false);
                } catch (Exception ex) {
                        log.warn("Error caught reading " + Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY + " from config file", ex);
                }
                if (checkRef) {
                        if (log.isDebugEnabled()) {
                                log.debug("verifyTModelKeyExists " + tmodelKey);
                        }
                        EntityManager em = PersistenceManager.getEntityManager();

                        if (em == null) {
                                //this is normally the Install class firing up
                                log.warn(new ErrorMessage("errors.tmodel.ReferentialIntegrityNullEM"));
                        } else {
                                //Collections.sort(buildInTmodels);
                                //if ((buildInTmodels, tmodelKey) == -1)
                                Tmodel modelTModel = null;
                                {
                                        EntityTransaction tx = em.getTransaction();
                                        try {

                                                tx.begin();
                                                modelTModel = em.find(org.apache.juddi.model.Tmodel.class, tmodelKey);

                                                if (modelTModel == null) {
                                                        checked = false;
                                                } else {
                                                     if (modelTModel.getCategoryBag()!=null)
                                                        for (org.apache.juddi.model.KeyedReference ref : modelTModel.getCategoryBag().getKeyedReferences()) {
                                                                if ("uddi-org:types:unchecked".equalsIgnoreCase(ref.getKeyName())) {
                                                                        checked = false;
                                                                        break;
                                                                }
                                                        }
                                                }

                                                tx.commit();

                                        } finally {
                                                if (tx.isActive()) {
                                                        tx.rollback();
                                                }
                                                em.close();
                                        }
                                        if (modelTModel == null) {
                                                throw new ValueNotAllowedException(new ErrorMessage("errors.tmodel.ReferencedKeyDoesNotExist", tmodelKey));
                                        }
                                }
                        }
                }
                return checked;
        }

        private boolean verifyTModelKeyChecked(Tmodel modelTModel) {
                boolean checked = true;
                if (modelTModel == null) {
                        checked = false;
                } else {
                        for (org.apache.juddi.model.KeyedReference ref : modelTModel.getCategoryBag().getKeyedReferences()) {
                                if ("uddi-org:types:unchecked".equalsIgnoreCase(ref.getTmodelKeyRef())) {
                                        checked = false;
                                        break;
                                }
                        }
                }
                return checked;
        }

        /**
         * throws if it doesn't exist, returns it if it does
         *
         * @param tmodelKey
         * @return null, or a TModel object
         * @throws ValueNotAllowedException
         * @since 3.3
         */
        private TModel verifyTModelKeyExists(String tmodelKey) throws ValueNotAllowedException, DispositionReportFaultMessage {
                TModel api = null;
                EntityManager em = PersistenceManager.getEntityManager();
                boolean found = false;
                if (em == null) {
                        log.warn(new ErrorMessage("errors.tmodel.ReferentialIntegrityNullEM"));
                } else {
                        Tmodel modelTModel = null;
                        {
                                EntityTransaction tx = em.getTransaction();
                                try {

                                        tx.begin();
                                        modelTModel = em.find(org.apache.juddi.model.Tmodel.class, tmodelKey);

                                        if (modelTModel != null) {
                                                found = true;
                                                api = new TModel();
                                                MappingModelToApi.mapTModel(modelTModel, api);
                                        }
                                        tx.commit();

                                } finally {
                                        if (tx.isActive()) {
                                                tx.rollback();
                                        }
                                        em.close();
                                }

                        }
                }
                if (!found) {
                        throw new ValueNotAllowedException(new ErrorMessage("errors.tmodel.ReferencedKeyDoesNotExist", tmodelKey));
                }
                return api;
        }

        private List<String> GetBindingKeysCheckedTModelKeyedReferenceBT(Map<String, TModel> cache, List<BindingTemplate> obj) {
                List<String> ret = new ArrayList<String>();

                if (obj == null) {
                        return ret;
                }
                for (BindingTemplate bt : obj) {
                        if (bt.getCategoryBag() != null) {
                                for (int i = 0; i < bt.getCategoryBag().getKeyedReference().size(); i++) {
                                        ret.addAll(GetBindingKeysCheckedTModelKeyedReference(cache, bt.getCategoryBag().getKeyedReference().get(i)));
                                }
                        }
                }

                return ret;
        }

        private List<String> GetBindingKeysCheckedTModelKeyedReferenceBS(Map<String, TModel> cache, List<BusinessService> obj) {
                List<String> ret = new ArrayList<String>();

                if (obj == null) {
                        return ret;
                }
                for (BusinessService bt : obj) {
                        if (bt.getCategoryBag() != null) {
                                for (int i = 0; i < bt.getCategoryBag().getKeyedReference().size(); i++) {
                                        ret.addAll(GetBindingKeysCheckedTModelKeyedReference(cache, bt.getCategoryBag().getKeyedReference().get(i)));
                                }
                        }
                        if (bt.getBindingTemplates() != null) {
                                ret.addAll(GetBindingKeysCheckedTModelKeyedReferenceBT(cache, bt.getBindingTemplates().getBindingTemplate()));
                        }
                }

                return ret;
        }

        private List<String> GetBindingKeysCheckedTModelKeyedReferenceBE(Map<String, TModel> cache, List<BusinessEntity> obj) {
                List<String> ret = new ArrayList<String>();

                if (obj == null) {
                        return ret;
                }
                for (BusinessEntity bt : obj) {
                        if (bt.getCategoryBag() != null) {
                                for (int i = 0; i < bt.getCategoryBag().getKeyedReference().size(); i++) {
                                        ret.addAll(GetBindingKeysCheckedTModelKeyedReference(cache, bt.getCategoryBag().getKeyedReference().get(i)));
                                }
                        }
                        if (bt.getIdentifierBag() != null) {
                                for (int i = 0; i < bt.getIdentifierBag().getKeyedReference().size(); i++) {
                                        ret.addAll(GetBindingKeysCheckedTModelKeyedReference(cache, bt.getIdentifierBag().getKeyedReference().get(i)));
                                }
                        }

                        if (bt.getBusinessServices() != null) {
                                ret.addAll(GetBindingKeysCheckedTModelKeyedReferenceBS(cache, bt.getBusinessServices().getBusinessService()));
                        }
                }
                return ret;
        }

        private List<String> GetBindingKeysCheckedTModelKeyedReferenceTM(Map<String, TModel> cache, List<TModel> obj) {
                List<String> ret = new ArrayList<String>();

                if (obj == null) {
                        return ret;
                }
                for (TModel bt : obj) {
                        if (bt.getCategoryBag() != null) {
                                for (int i = 0; i < bt.getCategoryBag().getKeyedReference().size(); i++) {
                                        ret.addAll(GetBindingKeysCheckedTModelKeyedReference(cache, bt.getCategoryBag().getKeyedReference().get(i)));
                                }
                        }
                        if (bt.getIdentifierBag() != null) {
                                for (int i = 0; i < bt.getIdentifierBag().getKeyedReference().size(); i++) {
                                        ret.addAll(GetBindingKeysCheckedTModelKeyedReference(cache, bt.getIdentifierBag().getKeyedReference().get(i)));
                                }
                        }
                }
                return ret;
        }

        /**
         * this should return a list of binding keys, only if the referenced kr
         * contains is validated by
         *
         * @param cache
         * @param get
         * @return
         */
        private List<String> GetBindingKeysCheckedTModelKeyedReference(Map<String, TModel> cache, KeyedReference get) {
                List<String> ret = new ArrayList<String>();
                TModel ref = null;
                log.debug("looking for is validated by for keyedref " + get.getTModelKey());
                if (cache.containsKey(get.getTModelKey())) {
                        ref = cache.get(get.getTModelKey());
                }
                if (ref == null) {
                        try {
                                ref = verifyTModelKeyExists(get.getTModelKey());
                                cache.put(get.getTModelKey(), ref);
                        } catch (Exception ex) {
                                log.error("unexpected error loading tmodel " + get.getTModelKey(), ex);
                        }
                }
                if (ref != null) {

                        ret.addAll(TModelContains(UDDIConstants.IS_VALIDATED_BY, ref));
                        ret.addAll(TModelContains(UDDIConstantsV2.IS_VALIDATED_BY, ref));

                }
                return ret;
        }

        /**
         * returns all keyvalues from ref.catbag and identbag where the tmodel
         * key matches
         *
         * @param key
         * @param ref
         * @return
         */
        private List<String> TModelContains(String key, TModel ref) {

                log.debug("looking for key=" + key + " from tModel " + ref.getTModelKey());
                List<String> ret = new ArrayList<String>();
                if (ref == null) {
                        return null;
                }
                if (ref.getCategoryBag() != null) {
                        for (int i = 0; i < ref.getCategoryBag().getKeyedReference().size(); i++) {
                                if (ref.getCategoryBag().getKeyedReference().get(i).getTModelKey().equalsIgnoreCase(key)) {
                                        log.debug("found reference for key=" + key + " from tModel " + ref.getTModelKey() + " validation endpoint " + ref.getCategoryBag().getKeyedReference().get(i).getKeyValue());
                                        ret.add(ref.getCategoryBag().getKeyedReference().get(i).getKeyValue());
                                }
                        }
                        for (int i = 0; i < ref.getCategoryBag().getKeyedReferenceGroup().size(); i++) {
                                for (int k = 0; k < ref.getCategoryBag().getKeyedReferenceGroup().get(i).getKeyedReference().size(); k++) {
                                        if (ref.getCategoryBag().getKeyedReferenceGroup().get(i).getKeyedReference().get(k).getTModelKey().equalsIgnoreCase(key)) {
                                                log.debug("found reference for key=" + key + " from tModel " + ref.getTModelKey() + " validation endpoint " + ref.getCategoryBag().getKeyedReferenceGroup().get(i).getKeyedReference().get(k).getKeyValue());
                                                ret.add(ref.getCategoryBag().getKeyedReferenceGroup().get(i).getKeyedReference().get(k).getKeyValue());
                                        }
                                }
                        }
                }
                if (ref.getIdentifierBag() != null) {
                        for (int i = 0; i < ref.getIdentifierBag().getKeyedReference().size(); i++) {
                                if (ref.getIdentifierBag().getKeyedReference().get(i).getTModelKey().equalsIgnoreCase(key)) {
                                        log.debug("found reference for key=" + key + " from tModel " + ref.getTModelKey() + " validation endpoint " + ref.getIdentifierBag().getKeyedReference().get(i).getKeyValue());
                                        ret.add(ref.getIdentifierBag().getKeyedReference().get(i).getKeyValue());
                                }
                        }
                }
                return ret;
        }

        /**
         * JUDDI-849 Each addressLine element MAY be adorned with two optional
         * descriptive attributes, keyName and keyValue. Both attributes MUST be
         * present in each address line if a tModelKey is specified in the
         * address structure. When no tModelKey is provided for the address
         * structure, the keyName and keyValue attributes have no defined
         * meaning.
         *
         * @param addressLine
         */
        private void validatedAddressLinesIfKeyDefined(List<AddressLine> addressLine) throws ValueNotAllowedException {
                String err = "";
                for (int i = 0; i < addressLine.size(); i++) {

                        if (addressLine.get(i).getKeyName() == null
                                || addressLine.get(i).getKeyName().trim().length() == 0) {
                                err += "addressLine(" + i + ").keyName,";
                        }
                        if (addressLine.get(i).getKeyValue() == null
                                || addressLine.get(i).getKeyValue().trim().length() == 0) {
                                err += "addressLine(" + i + ").keyValue,";
                        }
                        if (addressLine.get(i).getValue() == null
                                || addressLine.get(i).getValue().trim().length() == 0) {
                                err += "addressLine(" + i + ").value,";
                        }
                }
                if (err.length() > 0) {
                        throw new ValueNotAllowedException(new ErrorMessage("E_invalidValueAddressLine", err));
                }
        }

        private void validateCheckedTModelsBT(List<BindingTemplate> bindingTemplate, Configuration config) throws ValueNotAllowedException {

                boolean checkRef = false;
                try {
                        checkRef = config.getBoolean(Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY, false);
                } catch (Exception ex) {
                        log.warn("Error caught reading " + Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY + " from config file", ex);
                }

                if (!checkRef) {
                        return;
                }
                Map<String, TModel> cache = new HashMap<String, TModel>();
                List<String> bindings = GetBindingKeysCheckedTModelKeyedReferenceBT(cache, bindingTemplate);

                if (!bindings.isEmpty()) {
                        //get a unique list
                        bindings = new ArrayList(new HashSet(bindings));
                        for (int i = 0; i < bindings.size(); i++) {
                                //load binding from database
                                EntityManager em = PersistenceManager.getEntityManager();
                                org.apache.juddi.model.BindingTemplate find = em.find(org.apache.juddi.model.BindingTemplate.class, bindings.get(i));
                                if (find != null) {
                                        //parse endpoint
                                        String url = find.getAccessPointUrl();
                                        if (url == null) {
                                                url = find.getHostingRedirector();
                                        }
                                        if (url != null) {
                                                //call ValidateValuesFromWebService
                                                //optimization for localhost?
                                                ValidateValuesFromWebService.ValidateBinding(Rectify(url, config), bindingTemplate);
                                        }

                                }
                        }
                }
        }

        private void validateCheckedTModelsBS(List<BusinessService> bizlist, Configuration config) throws ValueNotAllowedException {
                boolean checkRef = false;
                try {
                        checkRef = config.getBoolean(Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY, false);
                } catch (Exception ex) {
                        log.warn("Error caught reading " + Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY + " from config file", ex);
                }
                if (!checkRef) {
                        return;
                }
                Map<String, TModel> cache = new HashMap<String, TModel>();
                List<String> bindings = GetBindingKeysCheckedTModelKeyedReferenceBS(cache, bizlist);

                if (!bindings.isEmpty()) {
                        //get a unique list
                        bindings = new ArrayList(new HashSet(bindings));
                        for (int i = 0; i < bindings.size(); i++) {
                                //load binding from database
                                EntityManager em = PersistenceManager.getEntityManager();
                                org.apache.juddi.model.BindingTemplate find = em.find(org.apache.juddi.model.BindingTemplate.class, bindings.get(i));
                                if (find != null) {
                                        //parse endpoint
                                        String url = find.getAccessPointUrl();
                                        if (url == null) {
                                                url = find.getHostingRedirector();
                                        }
                                        if (url != null) {
                                                //call ValidateValuesFromWebService
                                                //optimization for localhost?
                                                ValidateValuesFromWebService.ValidateService(Rectify(url, config), bizlist);
                                        }

                                }
                        }
                }
        }

        private void validateCheckedTModelsBE(List<BusinessEntity> entity, Configuration config) throws ValueNotAllowedException {
                boolean checkRef = false;
                try {
                        checkRef = config.getBoolean(Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY, false);
                } catch (Exception ex) {
                        log.warn("Error caught reading " + Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY + " from config file", ex);
                }
                if (!checkRef) {
                        return;
                }
                Map<String, TModel> cache = new HashMap<String, TModel>();
                List<String> bindings = GetBindingKeysCheckedTModelKeyedReferenceBE(cache, entity);

                if (!bindings.isEmpty()) {
                        //get a unique list
                        bindings = new ArrayList(new HashSet(bindings));
                        for (int i = 0; i < bindings.size(); i++) {
                                //load binding from database
                                EntityManager em = PersistenceManager.getEntityManager();
                                org.apache.juddi.model.BindingTemplate find = em.find(org.apache.juddi.model.BindingTemplate.class, bindings.get(i));
                                if (find != null) {
                                        //parse endpoint
                                        String url = find.getAccessPointUrl();
                                        if (url == null) {
                                                url = find.getHostingRedirector();
                                        }
                                        if (url != null) {
                                                //call ValidateValuesFromWebService
                                                //optimization for localhost?
                                                ValidateValuesFromWebService.ValidateBusiness(Rectify(url, config), entity);
                                        }

                                }
                        }
                }
        }

        private void validateCheckedTModelsTM(List<TModel> entity, Configuration config) throws ValueNotAllowedException {
                boolean checkRef = false;
                try {
                        checkRef = config.getBoolean(Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY, false);
                } catch (Exception ex) {
                        log.warn("Error caught reading " + Property.JUDDI_ENFORCE_REFERENTIAL_INTEGRITY + " from config file", ex);
                }
                if (!checkRef) {
                        return;
                }
                Map<String, TModel> cache = new HashMap<String, TModel>();
                List<String> bindings = GetBindingKeysCheckedTModelKeyedReferenceTM(cache, entity);

                if (!bindings.isEmpty()) {
                        //get a unique list
                        bindings = new ArrayList(new HashSet(bindings));
                        for (int i = 0; i < bindings.size(); i++) {
                                //load binding from database
                                EntityManager em = PersistenceManager.getEntityManager();
                                org.apache.juddi.model.BindingTemplate find = em.find(org.apache.juddi.model.BindingTemplate.class, bindings.get(i));
                                if (find != null) {
                                        //parse endpoint
                                        String url = find.getAccessPointUrl();
                                        if (url == null) {
                                                url = find.getHostingRedirector();
                                        }
                                        if (url != null) {
                                                log.debug("attempting vsv from " + url);
                                                //call ValidateValuesFromWebService
                                                //optimization for localhost?
                                                ValidateValuesFromWebService.ValidateTModel(Rectify(url, config), entity);
                                        }

                                }
                        }
                }
        }

        private String Rectify(String url, Configuration config) {
                //${juddi.server.baseurl}
                Properties p = new Properties();
                p.put("juddi.server.baseurl", config.getString("juddi.server.baseurl", Property.DEFAULT_BASE_URL));

                return TokenResolver.replaceTokens(url, p);
        }

        public void validateDeleteNode(EntityManager em, DeleteNode nodeID, ReplicationConfiguration cfg) throws DispositionReportFaultMessage {
                if (nodeID == null) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteClerk.NoInput"));
                }
                if (!((Publisher) publisher).isAdmin()) {
                        throw new UserMismatchException(new ErrorMessage("errors.deletepublisher.AdminReqd"));
                }
                if (nodeID.getNodeID() == null || nodeID.getNodeID().trim().equalsIgnoreCase("")) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.NoInput"));
                }
                //get the latest replication config
                if (cfg != null) {
                        if (cfg.getCommunicationGraph() != null) {
                                for (String node : cfg.getCommunicationGraph().getNode()) {
                                        if (node.equals(nodeID.getNodeID())) {
                                                throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.InReplicationConfig", nodeID.getNodeID()));
                                        }
                                }
                                for (int i = 0; i < cfg.getCommunicationGraph().getEdge().size(); i++) {
                                        if (nodeID.getNodeID().equals(cfg.getCommunicationGraph().getEdge().get(i).getMessageReceiver())) {
                                                throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.InReplicationConfig", nodeID.getNodeID()));
                                        }
                                        if (nodeID.getNodeID().equals(cfg.getCommunicationGraph().getEdge().get(i).getMessageSender())) {
                                                throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteNode.InReplicationConfig", nodeID.getNodeID()));
                                        }

                                }
                        }
                }

        }

        public void validateDeleteClerk(EntityManager em, DeleteClerk clerkID) throws DispositionReportFaultMessage {
                if (clerkID == null) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteClerk.NoInput"));
                }
                if (!((Publisher) publisher).isAdmin()) {
                        throw new UserMismatchException(new ErrorMessage("errors.deletepublisher.AdminReqd"));
                }
                if (clerkID.getClerkID() == null || clerkID.getClerkID().trim().equalsIgnoreCase("")) {
                        throw new InvalidKeyPassedException(new ErrorMessage("errors.deleteClerk.NoInput"));
                }

        }

        public void validateGetAllNodes() throws DispositionReportFaultMessage {
                if (!((Publisher) publisher).isAdmin()) {
                        throw new UserMismatchException(new ErrorMessage("errors.deletepublisher.AdminReqd"));
                }
        }

       private org.apache.juddi.v3.client.cryptor.DigSigUtil ds = null;

        private synchronized void initDigSig(Configuration config) {
                if (ds == null) {
                        
                        Properties p = new Properties();
                        /**
                         * <trustStorePath>truststore.jks</trustStorePath>
                         * <trustStoreType>JKS</trustStoreType>
                         * <trustStorePassword
                         * isPasswordEncrypted="false"
                         * cryptoProvider="org.apache.juddi.v3.client.crypto.AES128Cryptor">password</trustStorePassword>
                         *
                         * <checkTimestamps>true</checkTimestamps>
                         * <checkTrust>true</checkTrust>
                         * <checkRevocationCRL>true</checkRevocationCRL>
                         */
                        p.put(DigSigUtil.TRUSTSTORE_FILE, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStorePath", ""));
                        p.put(DigSigUtil.TRUSTSTORE_FILETYPE, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStoreType", ""));

                        String enc = config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStorePassword", "");
                        if (config.getBoolean(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStorePassword[@isPasswordEncrypted]", false)) {
                                log.debug("trust password is encrypted, decrypting...");
                                
                                String prov = config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "trustStorePassword[@cryptoProvider]", "");
                                try {
                                        p.setProperty(DigSigUtil.TRUSTSTORE_FILE_PASSWORD, CryptorFactory.getCryptor(prov).decrypt(enc));
                                } catch (Exception ex) {
                                        log.warn("unable to decrypt trust store password " + ex.getMessage());
                                        log.debug("unable to decrypt trust store password " + ex.getMessage(), ex);
                                }

                        } else if (!"".equals(enc)){
                                log.warn("Hey, you should consider encrypting your trust store password!");
                                p.setProperty(DigSigUtil.TRUSTSTORE_FILE_PASSWORD, enc);
                        }

                        p.put(DigSigUtil.CHECK_REVOCATION_STATUS_CRL, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "checkRevocationCRL", "true"));
                        p.put(DigSigUtil.CHECK_TRUST_CHAIN, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "checkTrust", "true"));
                        p.put(DigSigUtil.CHECK_TIMESTAMPS, config.getString(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_PREFIX + "checkTimestamps", "true"));

                        try {
                                ds = new DigSigUtil(p);
                        } catch (CertificateException ex) {
                                log.error("", ex);
                        }
                        //System.out.println("loaded from " + AppConfig.getConfigFileURL());
                        //p.list(System.out);
                }
        }

        private void validateSignaturesBinding(BindingTemplate bindingTemplate, Configuration config) throws FatalErrorException {
                boolean shouldcheck = config.getBoolean(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_ENABLE, false);
                initDigSig(config);
                if (shouldcheck && !bindingTemplate.getSignature().isEmpty() && ds != null) {
                        AtomicReference<String> outmsg = new AtomicReference<String>();
                        boolean ok = ds.verifySignedUddiEntity(bindingTemplate, outmsg);
                        if (!ok) {
                                throw new FatalErrorException(new ErrorMessage("errors.digitalsignature.validationfailure", bindingTemplate.getBindingKey() + " " + outmsg.get()));
                        }

                }
        }

        private void validateSignaturesService(BusinessService businessService, Configuration config) throws FatalErrorException {
                boolean shouldcheck = config.getBoolean(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_ENABLE, false);
                initDigSig(config);
                if (shouldcheck && !businessService.getSignature().isEmpty() && ds != null) {
                        AtomicReference<String> outmsg = new AtomicReference<String>();
                        boolean ok = ds.verifySignedUddiEntity(businessService, outmsg);
                        if (!ok) {
                                throw new FatalErrorException(new ErrorMessage("errors.digitalsignature.validationfailure", businessService.getServiceKey() + " " + outmsg.get()));
                        }

                }
        }

        private void validateSignaturesTModel(TModel tModel, Configuration config) throws FatalErrorException {
                boolean shouldcheck = config.getBoolean(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_ENABLE, false);
                initDigSig(config);
                if (shouldcheck && !tModel.getSignature().isEmpty() && ds != null) {
                        AtomicReference<String> outmsg = new AtomicReference<String>();
                        boolean ok = ds.verifySignedUddiEntity(tModel, outmsg);
                        if (!ok) {
                                throw new FatalErrorException(new ErrorMessage("errors.digitalsignature.validationfailure", tModel.getTModelKey() + " " + outmsg.get()));
                        }

                }
        }

        private void validateSignaturesBusiness(BusinessEntity businessEntity, Configuration config) throws FatalErrorException {
                boolean shouldcheck = config.getBoolean(Property.JUDDI_REJECT_ENTITIES_WITH_INVALID_SIG_ENABLE, false);
                initDigSig(config);
                if (shouldcheck && !businessEntity.getSignature().isEmpty() && ds != null) {
                        AtomicReference<String> outmsg = new AtomicReference<String>();
                        boolean ok = ds.verifySignedUddiEntity(businessEntity, outmsg);
                        if (!ok) {
                                throw new FatalErrorException(new ErrorMessage("errors.digitalsignature.validationfailure", businessEntity.getBusinessKey() + " " + outmsg.get()));
                        }

                }
        }

}
