1/*2 * Copyright 2014 The Apache Software Foundation.3 *4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 *8 * http://www.apache.org/licenses/LICENSE-2.09 *10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 */16package org.apache.juddi.validation.vsv;
1718import java.util.Collections;
19import java.util.List;
20import javax.persistence.EntityManager;
21import javax.persistence.EntityTransaction;
22import org.apache.juddi.config.PersistenceManager;
23import org.apache.juddi.model.Tmodel;
24import org.apache.juddi.v3.error.ErrorMessage;
25import org.apache.juddi.v3.error.InvalidValueException;
26import org.uddi.api_v3.BindingTemplate;
27import org.uddi.api_v3.BusinessEntity;
28import org.uddi.api_v3.BusinessService;
29import org.uddi.api_v3.KeyedReference;
30import org.uddi.api_v3.PublisherAssertion;
31import org.uddi.api_v3.TModel;
32import org.uddi.api_v3.TModelInstanceInfo;
33import org.uddi.v3_service.DispositionReportFaultMessage;
3435/**36 * UDDI provides a mechanism that may be used by publishers to tag their37 * businessEntities and tModels with information that identifies them according38 * to any number of identification systems. This tModel represents an identifier39 * system that may be used to identify the tModel or businessEntity that40 * logically replaces the tModel or businessEntity in which it is used. This41 * version of the isReplacedBy identifier system replaces the prior version of42 * this identifier system by providing a means for referring to replacement43 * entities that have version 3 format keys.44 *45 * It is often desirable to gracefully retire a tModel in favor of a46 * replacement. For example, when a Web service definition is replaced by an47 * incompatible version, the publisher of the specification may wish to leave48 * the tModel for the existing definition in place so that existing uses will49 * not be disturbed, while at the same time making it clear that there is a50 * replacement available. The UDDI isReplacedBy identifier system, coupled with51 * the behavior of UDDI with respect to obsolete tModels, fills this need by52 * allowing the obsolete tModel to point to its replacement. See Section 5.2.1153 * delete_tModel.54 *55 * The isReplacedBy identifier system exists in prior versions of UDDI.56 * keyedReferences that refer to this original isReplacedBy identifier system57 * contain entity keys in the version 1 and 2 formats (as UUIDs with the uuid or58 * no scheme prefix). When accessed using a prior version API in a multi-version59 * registry, the older isReplacedBy identifier system yields valid references to60 * businessEntity or tModel keys that are in the format of the prior version,61 * and thus remain valid. When viewed using the version 3 UDDI API these same62 * references to the earlier isReplacedBy identifier system contain invalid63 * version 3 format keys. A new version of this identifier system is required to64 * be able to reference the set of values defined by version 3 format keys.65 * 66* <p class="MsoBodyText">The keyValues in keyedReferences that refer to this67 * tModel must be tModelKeys or businessKeys. Such a keyValue specifies the68 * entity that is the replacement for the entity in which the keyedReference69 * appears. The above and further validation requirements are as follows:</p>70 *71 * <p class="MsoBodyText" style="margin-left:1.0in;text-indent:-.25in">a.<span72 * style="font:7.0pt "Times New73 * Roman""> </span>In the case where a74 * reference is made from an obsolete business entity the following validation75 * rules apply:</p>76 *77 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">1.<span78 * style="font:7.0pt "Times New79 * Roman""> </span>reference to a new80 * business entity; this is a valid operation</p>81 *82 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">2.<span83 * style="font:7.0pt "Times New84 * Roman""> </span>reference to self;85 * this is invalid</p>86 *87 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">3.<span88 * style="font:7.0pt "Times New89 * Roman""> </span>reference to a90 * service, binding or tModel; this is an invalid operation given that the91 * entity being pointed to must be a business</p>92 *93 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">4.<span94 * style="font:7.0pt "Times New95 * Roman""> </span>reference to another96 * publisher’s business; this is a valid operation; no ownership check is97 * made</p>98 *99 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">5.<span100 * style="font:7.0pt "Times New101 * Roman""> </span>reference to another102 * publisher’s service, binding or tModel; this is an invalid operation because103 * of a.3 above</p>104 *105 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">6.<span106 * style="font:7.0pt "Times New107 * Roman""> </span>reference to invalid108 * keys; this is an invalid operation; a key must be valid.</p>109 *110 * <p class="MsoBodyText" style="margin-left:1.0in;text-indent:-.25in">b.<span111 * style="font:7.0pt "Times New Roman""> 112 * </span>In the case where a reference is made from an obsolete tModel the113 * following validation rules apply:</p>114 *115 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">1.<span116 * style="font:7.0pt "Times New117 * Roman""> </span>reference to a new118 * tModel; this is a valid operation</p>119 *120 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">2.<span121 * style="font:7.0pt "Times New122 * Roman""> </span>reference to self;123 * this is invalid</p>124 *125 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">3.<span126 * style="font:7.0pt "Times New127 * Roman""> </span>reference to a128 * service, binding or business; this is an invalid operation given that the129 * entity being pointed to must be a tModel</p>130 *131 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">4.<span132 * style="font:7.0pt "Times New133 * Roman""> </span>reference to another134 * publisher’s tModel; this is a valid operation; no ownership check is made</p>135 *136 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">5.<span137 * style="font:7.0pt "Times New138 * Roman""> </span>reference to another139 * publisher’s service, binding or business; this is an invalid operation140 * because of b.3 above</p>141 *142 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">6.<span143 * style="font:7.0pt "Times New144 * Roman""> </span>reference to invalid145 * keys; this is an invalid operation; a key must be valid.</p>146 *147 * <p class="MsoBodyText" style="margin-left:1.25in;text-indent:-.25in">7.<span148 * style="font:7.0pt "Times New149 * Roman""> </span>reference to a150 * hidden tModel; this is a valid operation</p>151 *152 * <p class="MsoBodyText" style="margin-left:1.0in;text-indent:-.25in">c.<span153 * style="font:7.0pt "Times New154 * Roman""> </span>Adding isReplacedBy155 * to a service’s or binding’s category bag: this is a semantically wrong156 * operation and will be rejected. </p>157 *158 * <p class="MsoBodyText">When returning an error encountered in the above,159 * E_invalidValue will be returned to indicate that a value that was passed in a160 * keyValue attribute did not pass validation.</p>161 *162 * <p class="MsoBodyText">While this validation is intended at save time,163 * references to replacing business entities may become invalid if (A) the164 * business is deleted and (B) in V3 the business is deleted and then the key is165 * re-used for a different entity. As such, in a replicating registry, nodes166 * processing changeRecords related to business entities or tModels that refer167 * to (now) invalid or missing business or tModels entity keys respectively,168 * MUST NOT raise replication errors.</p>169 *170 * @author Alex O'Ree171 */172publicclassUddiuddiorgidentifierisreplacedbyimplementsValueSetValidator {
173174public String getMyKey(){
175return"uddi:uddi.org:identifier:isreplacedby";
176 }
177178 @Override
179publicvoid validateValuesBindingTemplate(List<BindingTemplate> items, String xpath) throws DispositionReportFaultMessage {
180if (items == null) {
181return;
182 }
183184for (int i = 0; i < items.size(); i++) {
185if (items.get(i).getCategoryBag() != null) {
186 AbstractSimpleValidator.validateKeyNotPresentKeyRef(items.get(i).getCategoryBag().getKeyedReference(), getMyKey(), "binding");
187 AbstractSimpleValidator.validateKeyNotPresentKeyRefGrp(items.get(i).getCategoryBag().getKeyedReferenceGroup(), getMyKey(), "binding");
188 }
189if (items.get(i).getTModelInstanceDetails() != null) {
190for (int k = 0; k < items.get(i).getTModelInstanceDetails().getTModelInstanceInfo().size(); k++) {
191if (items.get(i).getTModelInstanceDetails().getTModelInstanceInfo().get(k) != null) {
192if (getMyKey().equalsIgnoreCase(items.get(i).getTModelInstanceDetails().getTModelInstanceInfo().get(k).getTModelKey())) {
193thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "not allowed on binding templates"));
194 }
195 }
196 }
197 }
198 }
199 }
200201 @Override
202publicvoid validateValuesBusinessEntity(List<BusinessEntity> items) throws DispositionReportFaultMessage {
203if (items == null) {
204return;
205 }
206// In the case where a reference is made from an obsolete tModel the following validation rules apply:207 EntityManager em = PersistenceManager.getEntityManager();
208 EntityTransaction tx = em.getTransaction();
209try {
210 tx.begin();
211for (int i = 0; i < items.size(); i++) {
212if (items.get(i).getCategoryBag() != null) {
213for (int k = 0; k < items.get(i).getCategoryBag().getKeyedReference().size(); k++) {
214if (getMyKey().equalsIgnoreCase(items.get(i).getCategoryBag().getKeyedReference().get(k).getTModelKey())) {
215//reference to self; this is invalid216if (items.get(i).getCategoryBag().getKeyedReference().get(k).getTModelKey().equalsIgnoreCase(items.get(i).getBusinessKey())) {
217thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getCategoryBag().getKeyedReference().get(k).getKeyValue() + " can't reference itself"));
218 }
219220try {
221 org.apache.juddi.model.BusinessEntity find = em.find(org.apache.juddi.model.BusinessEntity.class, items.get(i).getCategoryBag().getKeyedReference().get(k).getKeyValue());
222if (find == null) {
223// reference to a new tModel; this is a valid operation224if (!ContainsBusinessKey(items, items.get(i).getCategoryBag().getKeyedReference().get(k).getKeyValue())) {
225thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getCategoryBag().getKeyedReference().get(k).getKeyValue() + " does not exist"));
226 }
227 }
228 } catch (ClassCastException c) {
229// reference to a service, binding or business; this is an invalid operation given that the entity being pointed to must be a tModel230thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getCategoryBag().getKeyedReference().get(k).getKeyValue() + " must be a business"));
231232 }
233 }
234 }
235 }
236if (items.get(i).getIdentifierBag() != null) {
237for (int k = 0; k < items.get(i).getIdentifierBag().getKeyedReference().size(); k++) {
238if (getMyKey().equalsIgnoreCase(items.get(i).getIdentifierBag().getKeyedReference().get(k).getTModelKey())) {
239//reference to self; this is invalid240if (items.get(i).getIdentifierBag().getKeyedReference().get(k).getTModelKey().equalsIgnoreCase(items.get(i).getBusinessKey())) {
241thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue() + " can't reference itself"));
242 }
243244try {
245 org.apache.juddi.model.BusinessEntity find = em.find(org.apache.juddi.model.BusinessEntity.class, items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue());
246if (find == null) {
247// reference to a new tModel; this is a valid operation248if (!ContainsBusinessKey(items, items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue())) {
249thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue() + " does not exist"));
250 }
251 }
252 } catch (ClassCastException c) {
253// reference to a service, binding or business; this is an invalid operation given that the entity being pointed to must be a tModel254thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue() + " must be a business"));
255256 }
257 }
258 }
259 }
260 }
261 tx.commit();
262 } catch (DispositionReportFaultMessage d) {
263throw d;
264 } finally {
265if (tx.isActive()) {
266 tx.rollback();
267 }
268 em.close();
269 }
270 }
271272 @Override
273publicvoid validateValuesBusinessService(List<BusinessService> items, String xpath) throws DispositionReportFaultMessage {
274if (items == null) {
275return;
276 }
277for (int i = 0; i < items.size(); i++) {
278if (items.get(i).getCategoryBag() != null) {
279 AbstractSimpleValidator.validateKeyNotPresentKeyRef(items.get(i).getCategoryBag().getKeyedReference(), getMyKey(), "service");
280 AbstractSimpleValidator.validateKeyNotPresentKeyRefGrp(items.get(i).getCategoryBag().getKeyedReferenceGroup(), getMyKey(), "service");
281 }
282if (items.get(i).getBindingTemplates() != null) {
283 validateValuesBindingTemplate(items.get(i).getBindingTemplates().getBindingTemplate(), xpath + xpath + "businessService(" + i + ").identifierBag.");
284 }
285 }
286 }
287288 @Override
289publicvoid validateValuesPublisherAssertion(List<PublisherAssertion> items) throws DispositionReportFaultMessage {
290if (items == null) {
291return;
292 }
293for (int i = 0; i < items.size(); i++) {
294 AbstractSimpleValidator.validateKeyNotPresentKeyRef(items.get(i).getKeyedReference(), getMyKey(), "publisherAssertion");
295 }
296 }
297298299 @Override
300publicvoid validateTmodelInstanceDetails(List<TModelInstanceInfo> tModelInstanceInfo, String xpath) throws DispositionReportFaultMessage {
301if (tModelInstanceInfo == null) {
302return;
303 }
304for (int k = 0; k < tModelInstanceInfo.size(); k++) {
305if (getMyKey().equalsIgnoreCase(tModelInstanceInfo.get(k).getTModelKey())) {
306thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "not allowed on tModel instance info"));
307 }
308 }
309 }
310311 @Override
312publicvoid validateValuesTModel(List<TModel> items) throws DispositionReportFaultMessage {
313if (items == null) {
314return;
315 }
316// In the case where a reference is made from an obsolete tModel the following validation rules apply:317 EntityManager em = PersistenceManager.getEntityManager();
318 EntityTransaction tx = em.getTransaction();
319320try {
321 tx.begin();
322for (int i = 0; i < items.size(); i++) {
323if (items.get(i).getCategoryBag() != null) {
324for (int k = 0; k < items.get(i).getCategoryBag().getKeyedReference().size(); k++) {
325if (getMyKey().equalsIgnoreCase(items.get(i).getCategoryBag().getKeyedReference().get(k).getTModelKey())) {
326//reference to self; this is invalid327if (items.get(i).getCategoryBag().getKeyedReference().get(k).getTModelKey().equalsIgnoreCase(items.get(i).getTModelKey())) {
328thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getCategoryBag().getKeyedReference().get(k).getKeyValue() + " can't reference itself"));
329 }
330331Tmodel find = null;
332try {
333 find = em.find(org.apache.juddi.model.Tmodel.class, items.get(i).getCategoryBag().getKeyedReference().get(k).getKeyValue());
334335 } catch (ClassCastException c) {
336// reference to a service, binding or business; this is an invalid operation given that the entity being pointed to must be a tModel337thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getCategoryBag().getKeyedReference().get(k).getKeyValue() + " must be a tModel"));
338339 }
340if (find == null) {
341// reference to a new tModel; this is a valid operation342if (!ContainsKey(items, items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue())) {
343thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getCategoryBag().getKeyedReference().get(k).getKeyValue() + " does not exist"));
344 }
345 }
346 }
347 }
348 }
349if (items.get(i).getIdentifierBag() != null) {
350for (int k = 0; k < items.get(i).getIdentifierBag().getKeyedReference().size(); k++) {
351if (getMyKey().equalsIgnoreCase(items.get(i).getIdentifierBag().getKeyedReference().get(k).getTModelKey())) {
352//reference to self; this is invalid353if (items.get(i).getIdentifierBag().getKeyedReference().get(k).getTModelKey().equalsIgnoreCase(items.get(i).getTModelKey())) {
354thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue() + " can't reference itself"));
355 }
356Tmodel find = null;
357try {
358 find = em.find(org.apache.juddi.model.Tmodel.class, items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue());
359360 } catch (ClassCastException c) {
361// reference to a service, binding or business; this is an invalid operation given that the entity being pointed to must be a tModel362thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue() + " must be a tModel"));
363364 }
365if (find == null) {
366// reference to a new tModel; this is a valid operation367if (!ContainsKey(items, items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue())) {
368thrownewInvalidValueException(newErrorMessage("errors.valuesetvalidation.invalidcontent", "Referenced key " + items.get(i).getIdentifierBag().getKeyedReference().get(k).getKeyValue() + " does not exist"));
369 }
370 }
371 }
372 }
373 }
374 }
375 tx.commit();
376 } catch (DispositionReportFaultMessage d) {
377throw d;
378 } finally {
379if (tx.isActive()) {
380 tx.rollback();
381 }
382 em.close();
383 }
384 }
385386 @Override
387public List<String> getValidValues() {
388return Collections.EMPTY_LIST;
389 }
390391privateboolean ContainsKey(List<TModel> items, String keyValue) {
392for (int i = 0; i < items.size(); i++) {
393if (items.get(i).getTModelKey().equalsIgnoreCase(keyValue)) {
394returntrue;
395 }
396 }
397return false;
398 }
399400privateboolean ContainsBusinessKey(List<BusinessEntity> items, String keyValue) {
401for (int i = 0; i < items.size(); i++) {
402if (items.get(i).getBusinessKey().equalsIgnoreCase(keyValue)) {
403returntrue;
404 }
405 }
406return false;
407 }
408409 }