public void validateBusinessService(EntityManager em, org.uddi.api_v3.BusinessService businessService, org.uddi.api_v3.BusinessEntity parent)
throws DispositionReportFaultMessage {
// A supplied businessService can't be null
if (businessService == null)
throw new ValueNotAllowedException(new ErrorMessage("errors.businessservice.NullInput"));
// 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();
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();
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);
}
// If existing service trying to be saved has a different parent key, then we have a problem
// TODO: moving services is allowed according to spec?
if (!parentKey.equalsIgnoreCase(bs.getBusinessEntity().getEntityKey()))
throw new InvalidKeyPassedException(new ErrorMessage("errors.invalidkey.businessservice.ParentMismatch", parentKey + ", " + bs.getBusinessEntity().getEntityKey()));
// Make sure publisher owns this entity.
if (!publisher.isOwner((UddiEntity)obj))
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.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.
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());