001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019: package org.netbeans.modules.wsdlextensions.snmp.validator;
020:
021: import java.text.MessageFormat;
022: import java.util.Collection;
023: import java.util.Collections;
024: import java.util.HashSet;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.ResourceBundle;
028:
029: import org.netbeans.modules.xml.wsdl.model.Binding;
030: import org.netbeans.modules.xml.wsdl.model.BindingInput;
031: import org.netbeans.modules.xml.wsdl.model.BindingOperation;
032: import org.netbeans.modules.xml.wsdl.model.BindingOutput;
033: import org.netbeans.modules.xml.wsdl.model.Definitions;
034: import org.netbeans.modules.xml.wsdl.model.Input;
035: import org.netbeans.modules.xml.wsdl.model.Operation;
036: import org.netbeans.modules.xml.wsdl.model.OperationParameter;
037: import org.netbeans.modules.xml.wsdl.model.Port;
038: import org.netbeans.modules.xml.wsdl.model.Service;
039: import org.netbeans.modules.xml.wsdl.model.WSDLModel;
040: import org.netbeans.modules.xml.wsdl.model.Message;
041: import org.netbeans.modules.xml.wsdl.model.Part;
042:
043: import org.netbeans.modules.xml.xam.Model;
044: import org.netbeans.modules.xml.xam.Model.State;
045: import org.netbeans.modules.xml.xam.dom.NamedComponentReference;
046: import org.netbeans.modules.xml.xam.Reference;
047: import org.netbeans.modules.xml.xam.spi.Validation;
048: import org.netbeans.modules.xml.xam.spi.Validation.ValidationType;
049: import org.netbeans.modules.xml.xam.spi.ValidationResult;
050: import org.netbeans.modules.xml.xam.spi.Validator;
051: import org.netbeans.modules.xml.xam.spi.Validator.ResultItem;
052:
053: import org.netbeans.modules.wsdlextensions.snmp.SNMPConstants;
054: import org.netbeans.modules.wsdlextensions.snmp.SNMPOperation;
055: import org.netbeans.modules.wsdlextensions.snmp.SNMPMessage;
056: import org.netbeans.modules.wsdlextensions.snmp.SNMPBinding;
057: import org.netbeans.modules.wsdlextensions.snmp.SNMPAddress;
058:
059: public class SNMPComponentValidator implements Validator {
060:
061: private static final ResourceBundle mMessages = ResourceBundle
062: .getBundle("org.netbeans.modules.wsdlextensions.snmp.validator.Bundle");
063:
064: private Validation mValidation;
065: private ValidationType mValidationType;
066: private ValidationResult mValidationResult;
067:
068: public static final ValidationResult EMPTY_RESULT = new ValidationResult(
069: Collections.EMPTY_SET, Collections.EMPTY_SET);
070:
071: public SNMPComponentValidator() {
072: }
073:
074: /**
075: * Returns name of this validation service.
076: */
077: public String getName() {
078: return getClass().getName();
079: }
080:
081: /**
082: * Validates given model.
083: *
084: * @param model model to validate.
085: * @param validation reference to the validation context.
086: * @param validationType the type of validation to perform
087: * @return ValidationResult.
088: */
089: public ValidationResult validate(Model model,
090: Validation validation, ValidationType validationType) {
091: mValidation = validation;
092: mValidationType = validationType;
093:
094: HashSet<ResultItem> results = new HashSet<ResultItem>();
095: HashSet<Model> models = new HashSet<Model>();
096: models.add(model);
097: mValidationResult = new ValidationResult(results, models);
098:
099: // Traverse the model
100: if (model instanceof WSDLModel) {
101: WSDLModel wsdlModel = (WSDLModel) model;
102:
103: if (model.getState() == State.NOT_WELL_FORMED) {
104: return EMPTY_RESULT;
105: }
106:
107: Definitions defs = wsdlModel.getDefinitions();
108: Iterator<Binding> bindings = defs.getBindings().iterator();
109:
110: while (bindings.hasNext()) {
111: Binding binding = bindings.next();
112:
113: if (binding.getType() == null
114: || binding.getType().get() == null) {
115: continue;
116: }
117:
118: int numSNMPBindings = binding.getExtensibilityElements(
119: SNMPBinding.class).size();
120: if (numSNMPBindings == 0) {
121: continue;
122: }
123:
124: if (numSNMPBindings > 0 && numSNMPBindings != 1) {
125: results
126: .add(new Validator.ResultItem(
127: this ,
128: Validator.ResultType.ERROR,
129: binding,
130: getMessage(
131: "SNMPBindingValidation.ONLY_ONE_SNMP_BINDING_ALLOWED",
132: new Object[] {
133: binding.getName(),
134: new Integer(
135: numSNMPBindings) })));
136: }
137:
138: Iterator<BindingOperation> bindingOps = binding
139: .getBindingOperations().iterator();
140: boolean foundSNMPOp = false;
141: int msgCnt = 0;
142: while (bindingOps.hasNext()) {
143: BindingOperation bindingOp = bindingOps.next();
144: List<SNMPOperation> snmpOpsList = bindingOp
145: .getExtensibilityElements(SNMPOperation.class);
146: Iterator<SNMPOperation> snmpOps = snmpOpsList
147: .iterator();
148:
149: while (snmpOps.hasNext()) {
150: validate(bindingOp, snmpOps.next());
151: }
152:
153: if (snmpOpsList.size() > 0) {
154: foundSNMPOp = true;
155: if (!checkSignature(bindingOp)) {
156: results
157: .add(new Validator.ResultItem(
158: this ,
159: Validator.ResultType.ERROR,
160: bindingOp,
161: getMessage(
162: "SNMPBindingValidation.OP_SIG_MISMATCH_BINDING_ABSTRACT",
163: new Object[] {
164: binding
165: .getName(),
166: bindingOp
167: .getName() })));
168: continue;
169: }
170: BindingInput bindingInput = bindingOp
171: .getBindingInput();
172: if (bindingInput != null) {
173: msgCnt = 0;
174: // assumption:
175: // under <input>, there could be one of the following:
176: // <snmp:message>
177: // but only one is allowed;
178: //
179: Iterator<SNMPMessage> snmpMessages = bindingInput
180: .getExtensibilityElements(
181: SNMPMessage.class)
182: .iterator();
183: if (snmpMessages != null) {
184: while (snmpMessages.hasNext()) {
185: msgCnt++;
186: SNMPMessage snmpMessage = snmpMessages
187: .next();
188: validate(bindingOp, bindingInput
189: .getInput().get(),
190: snmpMessage);
191: }
192: if (msgCnt > 1) {
193: results
194: .add(new Validator.ResultItem(
195: this ,
196: Validator.ResultType.ERROR,
197: bindingInput,
198: getMessage(
199: "SNMPBindingValidation.ATMOST_ONE_MESSAGE_IN_INPUT",
200: new Object[] {
201: bindingOp
202: .getName(),
203: new Integer(
204: msgCnt),
205: bindingInput
206: .getName() })));
207: }
208: }
209:
210: if (msgCnt == 0) {
211: results
212: .add(new Validator.ResultItem(
213: this ,
214: Validator.ResultType.ERROR,
215: bindingInput,
216: getMessage(
217: "SNMPBindingValidation.NO_MESSAGE_FOUND_IN_INPUT",
218: new Object[] {
219: bindingOp
220: .getName(),
221: bindingInput
222: .getName() })));
223: }
224: }
225:
226: BindingOutput bindingOutput = bindingOp
227: .getBindingOutput();
228: if (bindingOutput != null) {
229: // reset and do output checking
230: msgCnt = 0;
231:
232: Iterator<SNMPMessage> snmpMessages = bindingOutput
233: .getExtensibilityElements(
234: SNMPMessage.class)
235: .iterator();
236: if (snmpMessages != null) {
237: while (snmpMessages.hasNext()) {
238: msgCnt++;
239: SNMPMessage snmpMessage = snmpMessages
240: .next();
241: validate(bindingOp, bindingOutput
242: .getOutput().get(),
243: snmpMessage);
244: }
245: if (msgCnt > 1) {
246: results
247: .add(new Validator.ResultItem(
248: this ,
249: Validator.ResultType.ERROR,
250: bindingOutput,
251: getMessage(
252: "SNMPBindingValidation.ATMOST_ONE_MESSAGE_IN_OUTPUT",
253: new Object[] {
254: bindingOp
255: .getName(),
256: new Integer(
257: msgCnt),
258: bindingOutput
259: .getName() })));
260: }
261: }
262:
263: if (msgCnt == 0) {
264: results
265: .add(new Validator.ResultItem(
266: this ,
267: Validator.ResultType.ERROR,
268: bindingOutput,
269: getMessage(
270: "SNMPBindingValidation.NO_MESSAGE_FOUND_IN_OUTPUT",
271: new Object[] {
272: bindingOp
273: .getName(),
274: bindingOutput
275: .getName() })));
276: }
277: }
278: }
279:
280: }
281: // there is snmp:binding but no snmp:operation
282: if (numSNMPBindings > 0 && !foundSNMPOp) {
283: results
284: .add(new Validator.ResultItem(
285: this ,
286: Validator.ResultType.ERROR,
287: binding,
288: getMessage(
289: "SNMPBindingValidation.MISSING_SNMP_OPERATION",
290: new Object[] { binding
291: .getName() })));
292: }
293: // there is no snmp:binding but there are snmp:operation
294: if (numSNMPBindings == 0 && foundSNMPOp) {
295: results
296: .add(new Validator.ResultItem(
297: this ,
298: Validator.ResultType.ERROR,
299: binding,
300: getMessage(
301: "SNMPBindingValidation.SNMP_OPERATION_WO_SNMP_BINDING",
302: new Object[] { binding
303: .getName() })));
304: }
305: }
306:
307: Iterator<Service> services = defs.getServices().iterator();
308: while (services.hasNext()) {
309: Iterator<Port> ports = services.next().getPorts()
310: .iterator();
311: while (ports.hasNext()) {
312: Port port = ports.next();
313: if (port.getBinding() != null) {
314: Binding binding = port.getBinding().get();
315: if (binding != null) {
316: int numRelatedSNMPBindings = binding
317: .getExtensibilityElements(
318: SNMPBinding.class).size();
319: List<SNMPAddress> snmpAddressList = port
320: .getExtensibilityElements(SNMPAddress.class);
321: Iterator<SNMPAddress> snmpAddresses = snmpAddressList
322: .iterator();
323: if ((numRelatedSNMPBindings > 0)
324: && (snmpAddressList.size() == 0)) {
325: results
326: .add(new Validator.ResultItem(
327: this ,
328: Validator.ResultType.ERROR,
329: port,
330: getMessage(
331: "SNMPAddressValidation.MISSING_SNMP_ADDRESS",
332: new Object[] {
333: port
334: .getName(),
335: new Integer(
336: numRelatedSNMPBindings) })));
337: }
338:
339: if (snmpAddressList.size() > 1) {
340: results
341: .add(new Validator.ResultItem(
342: this ,
343: Validator.ResultType.ERROR,
344: port,
345: getMessage(
346: "SNMPAddressValidation.ONLY_ONE_SNMP_ADDRESS_ALLOWED",
347: new Object[] {
348: port
349: .getName(),
350: new Integer(
351: snmpAddressList
352: .size()) })));
353: }
354: while (snmpAddresses.hasNext()) {
355: SNMPAddress snmpAddress = snmpAddresses
356: .next();
357: if (numRelatedSNMPBindings > 0) {
358: validate(snmpAddress, binding);
359: }
360: }
361: }
362: }
363: }
364: }
365: }
366: // Clear out our state
367: mValidation = null;
368: mValidationType = null;
369:
370: return mValidationResult;
371: }
372:
373: private void validate(SNMPAddress target, Binding binding) {
374: // validate connection url
375: Collection<ResultItem> results = mValidationResult
376: .getValidationResult();
377:
378: int port = target.getPort();
379: boolean isMof = false;
380: for (Iterator<BindingOperation> iter = binding
381: .getBindingOperations().iterator(); iter.hasNext();) {
382: BindingOperation op = iter.next();
383: List<SNMPOperation> snmpOps = op
384: .getExtensibilityElements(SNMPOperation.class);
385: if (snmpOps.size() > 0) {
386: SNMPOperation snmpOp = snmpOps.get(0);
387: if (SNMPConstants.MOF.equals(snmpOp.getType())) {
388: isMof = true;
389: break;
390: }
391: }
392: }
393:
394: if (isMof && port <= 0) {
395: results.add(new Validator.ResultItem(this ,
396: Validator.ResultType.ERROR, target,
397: getMessage("SNMPAddress.INVALID_PORT",
398: new Object[] {})));
399: }
400:
401: }
402:
403: private void validate(BindingOperation bindingOp,
404: SNMPOperation target) {
405: Collection<ResultItem> results = mValidationResult
406: .getValidationResult();
407:
408: // ToDo: validate SNMP operation
409: String mep = "in-only";
410: boolean hasInput = bindingOp.getBindingInput() != null;
411: boolean hasOutput = bindingOp.getBindingOutput() != null;
412:
413: if (hasInput && hasOutput) {
414: mep = "in-out";
415: }
416:
417: String type = target.getType();
418: if (type == null || type.equals("")) {
419: results.add(new Validator.ResultItem(this ,
420: Validator.ResultType.ERROR, target, getMessage(
421: "SNMPOperation.TYPE_EMPTY",
422: new Object[] { bindingOp.getName() })));
423: return;
424: }
425:
426: String mofId = target.getMofId();
427: String adaptationId = target.getAdaptationId();
428: String mofIdRef = target.getMofIdRef();
429:
430: if (type.equals(SNMPConstants.MOF)) {
431: if (mofId == null || mofId.equals("")) {
432: results.add(new Validator.ResultItem(this ,
433: Validator.ResultType.ERROR, target, getMessage(
434: "SNMPOperation.MOFID_EMPTY",
435: new Object[] { bindingOp.getName() })));
436: }
437: if (adaptationId != null && !adaptationId.equals("")) {
438: results
439: .add(new Validator.ResultItem(
440: this ,
441: Validator.ResultType.ERROR,
442: target,
443: getMessage(
444: "SNMPOperation.ADAPTATIONID_NOT_NEEDED",
445: new Object[] { bindingOp
446: .getName() })));
447: }
448: if (mofIdRef != null && !mofIdRef.equals("")) {
449: results.add(new Validator.ResultItem(this ,
450: Validator.ResultType.ERROR, target, getMessage(
451: "SNMPOperation.MOFIDREF_NOT_NEEDED",
452: new Object[] { bindingOp.getName() })));
453: }
454: } else if (type.equals(SNMPConstants.ADAPTATION)) {
455: if (adaptationId == null || adaptationId.equals("")) {
456: results.add(new Validator.ResultItem(this ,
457: Validator.ResultType.ERROR, target, getMessage(
458: "SNMPOperation.ADAPTATIONID_EMPTY",
459: new Object[] { bindingOp.getName() })));
460: }
461: if (mofId != null && !mofId.equals("")) {
462: results.add(new Validator.ResultItem(this ,
463: Validator.ResultType.ERROR, target, getMessage(
464: "SNMPOperation.MOFID_NOT_NEEDED",
465: new Object[] { bindingOp.getName() })));
466: }
467: if (mofIdRef != null && !mofIdRef.equals("")) {
468: results.add(new Validator.ResultItem(this ,
469: Validator.ResultType.ERROR, target, getMessage(
470: "SNMPOperation.MOFIDREF_NOT_NEEDED",
471: new Object[] { bindingOp.getName() })));
472: }
473: } else if (type.equals(SNMPConstants.PM)) {
474: if (mofIdRef == null || mofIdRef.equals("")) {
475: results.add(new Validator.ResultItem(this ,
476: Validator.ResultType.ERROR, target, getMessage(
477: "SNMPOperation.MOFIDREF_EMPTY",
478: new Object[] { bindingOp.getName() })));
479: }
480: if (mofId != null && !mofId.equals("")) {
481: results.add(new Validator.ResultItem(this ,
482: Validator.ResultType.ERROR, target, getMessage(
483: "SNMPOperation.MOFID_NOT_NEEDED",
484: new Object[] { bindingOp.getName() })));
485: }
486: if (adaptationId != null && !adaptationId.equals("")) {
487: results
488: .add(new Validator.ResultItem(
489: this ,
490: Validator.ResultType.ERROR,
491: target,
492: getMessage(
493: "SNMPOperation.ADAPTATIONID_NOT_NEEDED",
494: new Object[] { bindingOp
495: .getName() })));
496: }
497: } else {
498: results.add(new Validator.ResultItem(this ,
499: Validator.ResultType.ERROR, target, getMessage(
500: "SNMPOperation.UNKNOWN_TYPE", new Object[] {
501: bindingOp.getName(), type })));
502: }
503:
504: }
505:
506: private void validate(BindingOperation bindingOp,
507: OperationParameter opParam, SNMPMessage target) {
508: Collection<ResultItem> results = mValidationResult
509: .getValidationResult();
510:
511: // SNMP validation
512: String snmpTrapPart = target.getTrapPart();
513: if (snmpTrapPart == null || snmpTrapPart.length() == 0) {
514: results
515: .add(new Validator.ResultItem(
516: this ,
517: Validator.ResultType.ERROR,
518: target,
519: getMessage(
520: "SNMPMessage.TRAPPART_NOT_SPECIFIED",
521: new Object[] {
522: bindingOp.getName(),
523: (opParam instanceof Input) ? "input"
524: : "output",
525: opParam.getName() })));
526: } else {
527: // make sure trapPart references a vald wsdl message part
528: if (!referencesValidMessagePart(opParam.getMessage(),
529: snmpTrapPart)) {
530: results
531: .add(new Validator.ResultItem(
532: this ,
533: Validator.ResultType.ERROR,
534: target,
535: getMessage(
536: "SNMPMessage.TRAP_PART_REFERENCES_NON_EXISTENT_PART",
537: new Object[] {
538: bindingOp.getName(),
539: (opParam instanceof Input) ? "input"
540: : "output",
541: opParam.getName(),
542: snmpTrapPart,
543: opParam.getMessage()
544: .getQName() })));
545: }
546: }
547:
548: }
549:
550: private boolean checkSignature(BindingOperation bindingOp/*, Object inputChild, Object outputChild*/) {
551: boolean result = true;
552: Reference<Operation> opRef = bindingOp.getOperation();
553: if (opRef == null)
554: return false;
555: Operation op = opRef.get();
556: if (op == null)
557: return false;
558: if ((op.getInput() == null && bindingOp.getBindingInput() == null /*&& inputChild == null*/)
559: || (op.getInput() != null && bindingOp
560: .getBindingInput() != null /*&& inputChild != null*/)) {
561:
562: } else {
563: result = false;
564: }
565:
566: if ((op.getOutput() == null && bindingOp.getBindingOutput() == null /*&& outputChild == null*/)
567: || (op.getOutput() != null && bindingOp
568: .getBindingOutput() != null /*&& outputChild != null*/)) {
569:
570: } else {
571: result = false;
572: }
573: return result;
574: }
575:
576: private boolean referencesValidMessagePart(
577: NamedComponentReference<Message> wsdlMessage,
578: String partName) {
579:
580: // Let wsdl validator catch undefined message for operation input or output
581: if (wsdlMessage == null || wsdlMessage.get() == null
582: || wsdlMessage.get().getParts() == null) {
583: return true;
584: }
585:
586: boolean isValdPartReference = false;
587: Iterator<Part> partIter = wsdlMessage.get().getParts()
588: .iterator();
589: while (partIter.hasNext()) {
590: Part p = partIter.next();
591: if (p.getName().equals(partName)) {
592: isValdPartReference = true;
593: break;
594: }
595: }
596: return isValdPartReference;
597: }
598:
599: private String getMessage(String key, String param) {
600: return getMessage(key, new Object[] { param });
601: }
602:
603: private String getMessage(String key, Object[] params) {
604: String fmt = mMessages.getString(key);
605: if (params != null) {
606: return MessageFormat.format(fmt, params);
607: } else {
608: return fmt;
609: }
610: }
611: }
|