Merge "Fix build errors in autorelease full clean build"
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.common / src / main / java / org / eclipse / winery / common / ModelUtilities.java
1 /*******************************************************************************
2  * Copyright (c) 2013 University of Stuttgart.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * and the Apache License 2.0 which both accompany this distribution,
6  * and are available at http://www.eclipse.org/legal/epl-v10.html
7  * and http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Contributors:
10  *     Oliver Kopp - initial API and implementation
11  *******************************************************************************/
12 package org.eclipse.winery.common;
13
14 import java.lang.reflect.Method;
15 import java.util.Iterator;
16 import java.util.Map;
17 import java.util.Properties;
18 import java.util.UUID;
19
20 import javax.xml.XMLConstants;
21 import javax.xml.namespace.QName;
22 import javax.xml.parsers.DocumentBuilder;
23 import javax.xml.parsers.DocumentBuilderFactory;
24 import javax.xml.parsers.ParserConfigurationException;
25
26 import org.apache.commons.lang3.StringUtils;
27 import org.eclipse.winery.common.constants.Namespaces;
28 import org.eclipse.winery.common.constants.QNames;
29 import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKV;
30 import org.eclipse.winery.common.propertydefinitionkv.PropertyDefinitionKVList;
31 import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition;
32 import org.eclipse.winery.model.tosca.TBoundaryDefinitions;
33 import org.eclipse.winery.model.tosca.TCapability;
34 import org.eclipse.winery.model.tosca.TCapabilityDefinition;
35 import org.eclipse.winery.model.tosca.TEntityTemplate;
36 import org.eclipse.winery.model.tosca.TEntityType;
37 import org.eclipse.winery.model.tosca.TExtensibleElements;
38 import org.eclipse.winery.model.tosca.TNodeTemplate;
39 import org.eclipse.winery.model.tosca.TNodeTemplate.Capabilities;
40 import org.eclipse.winery.model.tosca.TNodeTemplate.Requirements;
41 import org.eclipse.winery.model.tosca.TNodeType;
42 import org.eclipse.winery.model.tosca.TPlan;
43 import org.eclipse.winery.model.tosca.TPlans;
44 import org.eclipse.winery.model.tosca.TRelationshipTemplate;
45 import org.eclipse.winery.model.tosca.TRelationshipTemplate.SourceElement;
46 import org.eclipse.winery.model.tosca.TRelationshipTemplate.TargetElement;
47 import org.eclipse.winery.model.tosca.TRelationshipType;
48 import org.eclipse.winery.model.tosca.TRequirement;
49 import org.eclipse.winery.model.tosca.TRequirementDefinition;
50 import org.eclipse.winery.model.tosca.TServiceTemplate;
51 import org.eclipse.winery.model.tosca.TTopologyTemplate;
52 import org.slf4j.LoggerFactory;
53 import org.w3c.dom.Comment;
54 import org.w3c.dom.Document;
55 import org.w3c.dom.Element;
56 import org.w3c.dom.Node;
57 import org.w3c.dom.NodeList;
58 import org.w3c.dom.Text;
59
60 public class ModelUtilities {
61         
62         private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ModelUtilities.class);
63         
64         
65         /**
66          * This is a special method for Winery. Winery allows to define a property
67          * definition by specifying name/type values. Instead of parsing the
68          * extensible elements returned TDefinitions, this method is a convenience
69          * method to access this information
70          * 
71          * @param t the entitytype to read the properties definition from
72          * @return a WinerysPropertiesDefinition object, which includes a map of
73          *         name/type-pairs denoting the associated property definitions. A
74          *         default element name and namespace is added if it is not defined
75          *         in the underlying XML. null if no Winery specific KV properties
76          *         are defined for the given entity type
77          */
78         public static WinerysPropertiesDefinition getWinerysPropertiesDefinition(TEntityType et) {
79                 // similar implementation as org.eclipse.winery.repository.resources.entitytypes.properties.PropertiesDefinitionResource.getListFromEntityType(TEntityType)
80                 WinerysPropertiesDefinition res = null;
81                 for (Object o : et.getAny()) {
82                         if (o instanceof WinerysPropertiesDefinition) {
83                                 res = (WinerysPropertiesDefinition) o;
84                         }
85                 }
86                 
87                 if (res != null) {
88                         // we put defaults if elementname and namespace have not been set
89                         
90                         if (res.getElementName() == null) {
91                                 res.setElementName("Properties");
92                         }
93                         
94                         if (res.getNamespace() == null) {
95                                 // we use the targetnamespace of the original element
96                                 String ns = et.getTargetNamespace();
97                                 if (!ns.endsWith("/")) {
98                                         ns += "/";
99                                 }
100                                 ns += "propertiesdefinition/winery";
101                                 res.setNamespace(ns);
102                         }
103                 }
104                 
105                 return res;
106         }
107         
108         /**
109          * This is a special method for Winery. Winery allows to define a property
110          * by specifying name/value values. Instead of parsing the XML contained in
111          * TNodeType, this method is a convenience method to access this information
112          * 
113          * The return type "Properties" is used because of the key/value properties.
114          * 
115          * @param template the node template to get the associated properties
116          */
117         public static Properties getPropertiesKV(TEntityTemplate template) {
118                 Properties properties = new Properties();
119                 org.eclipse.winery.model.tosca.TEntityTemplate.Properties tprops = template.getProperties();
120                 if (tprops != null) {
121                         // no checking for validity, just reading
122                         Element el = (Element) tprops.getAny();
123                         if (el == null) {
124                                 // somehow invalid .tosca. We return empty properties instead of throwing a NPE
125                                 return properties;
126                         }
127                         NodeList childNodes = el.getChildNodes();
128                         for (int i = 0; i < childNodes.getLength(); i++) {
129                                 Node item = childNodes.item(i);
130                                 if (item instanceof Element) {
131                                         String key = item.getLocalName();
132                                         String value = item.getTextContent();
133                                         properties.put(key, value);
134                                 }
135                         }
136                 }
137                 return properties;
138         }
139         
140         /**
141          * This is a special method for Winery. Winery allows to define a property
142          * by specifying name/value values. We convert the given Properties to XML.
143          * 
144          * @param wpd the Winery's properties definition of the type of the given
145          *            template (i.e., wpd =
146          *            getWinerysPropertiesDefinition(template.getType()))
147          * @param template the node template to set the associated properties
148          */
149         public static void setPropertiesKV(WinerysPropertiesDefinition wpd, TEntityTemplate template, Properties properties) {
150                 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
151                 DocumentBuilder db;
152                 try {
153                         db = dbf.newDocumentBuilder();
154                 } catch (ParserConfigurationException e) {
155                         ModelUtilities.logger.debug(e.getMessage(), e);
156                         throw new IllegalStateException("Could not instantiate document builder", e);
157                 }
158                 Document doc = db.newDocument();
159                 
160                 Element root = doc.createElementNS(wpd.getNamespace(), wpd.getElementName());
161                 doc.appendChild(root);
162                 
163                 // we produce the serialization in the same order the XSD would be generated (because of the usage of xsd:sequence)
164                 for (PropertyDefinitionKV prop : wpd.getPropertyDefinitionKVList()) {
165                         // we always write the element tag as the XSD forces that
166                         Element element = doc.createElementNS(wpd.getNamespace(), prop.getKey());
167                         root.appendChild(element);
168                         String value = properties.getProperty(prop.getKey());
169                         if (value != null) {
170                                 Text text = doc.createTextNode(value);
171                                 element.appendChild(text);
172                         }
173                 }
174                 
175                 org.eclipse.winery.model.tosca.TEntityTemplate.Properties tprops = new org.eclipse.winery.model.tosca.TEntityTemplate.Properties();
176                 tprops.setAny(doc.getDocumentElement());
177                 template.setProperties(tprops);
178         }
179         
180         /**
181          * Generates a XSD when Winery's K/V properties are used. This method is put
182          * here instead of WinerysPropertiesDefinitionResource to avoid generating
183          * the subresource
184          * 
185          * public because of the usage by TOSCAEXportUtil
186          * 
187          * @return empty Document, if Winery's Properties Definition is not fully
188          *         filled (e.g., no wrapping element defined)
189          */
190         public static Document getWinerysPropertiesDefinitionXSDAsDocument(WinerysPropertiesDefinition wpd) {
191                 /*
192                  * This is a quick hack: an XML schema container is created for each
193                  * element. Smarter solution: create a hash from namespace to XML schema
194                  * element and re-use that for each new element
195                 * Drawback of "smarter" solution: not a single XSD file any more
196                  */
197                 DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
198                 DocumentBuilder docBuilder;
199                 try {
200                         docBuilder = docFactory.newDocumentBuilder();
201                 } catch (ParserConfigurationException e) {
202                         ModelUtilities.logger.debug(e.getMessage(), e);
203                         throw new IllegalStateException("Could not instantiate document builder", e);
204                 }
205                 Document doc = docBuilder.newDocument();
206                 
207                 if (!ModelUtilities.allRequiredFieldsNonNull(wpd)) {
208                         // wpd not fully filled -> valid XSD cannot be provided
209                         // fallback: add comment and return "empty" document
210                         Comment comment = doc.createComment("Required fields are missing in Winery's key/value properties definition.");
211                         doc.appendChild(comment);
212                         return doc;
213                 }
214                 
215                 // create XSD schema container
216                 Element schemaElement = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "schema");
217                 doc.appendChild(schemaElement);
218                 schemaElement.setAttribute("elementFormDefault", "qualified");
219                 schemaElement.setAttribute("attributeFormDefault", "unqualified");
220                 schemaElement.setAttribute("targetNamespace", wpd.getNamespace());
221                 
222                 // create XSD element itself
223                 Element el = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "element");
224                 schemaElement.appendChild(el);
225                 el.setAttribute("name", wpd.getElementName());
226                 Element el2 = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "complexType");
227                 el.appendChild(el2);
228                 el = el2;
229                 el2 = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "sequence");
230                 el.appendChild(el2);
231                 el = el2;
232                 
233                 // currently, "xsd" is a hardcoded prefix in the type definition
234                 el.setAttribute("xmlns:xsd", XMLConstants.W3C_XML_SCHEMA_NS_URI);
235                 
236                 for (PropertyDefinitionKV prop : wpd.getPropertyDefinitionKVList()) {
237                         el2 = doc.createElementNS(XMLConstants.W3C_XML_SCHEMA_NS_URI, "element");
238                         el.appendChild(el2);
239                         el2.setAttribute("name", prop.getKey());
240                         // prop.getType has the prefix included
241                         el2.setAttribute("type", prop.getType());
242                 }
243                 
244                 return doc;
245         }
246         
247         /**
248          * Removes an existing Winery's Properties definition. If no such definition
249          * exists, the TEntityType is not modified
250          */
251         public static void removeWinerysPropertiesDefinition(TEntityType et) {
252                 for (Iterator<Object> iterator = et.getAny().iterator(); iterator.hasNext();) {
253                         Object o = iterator.next();
254                         if (o instanceof WinerysPropertiesDefinition) {
255                                 iterator.remove();
256                                 break;
257                         }
258                 }
259         }
260         
261         public static void replaceWinerysPropertiesDefinition(TEntityType et, WinerysPropertiesDefinition wpd) {
262                 ModelUtilities.removeWinerysPropertiesDefinition(et);
263                 et.getAny().add(wpd);
264         }
265         
266         public static String getBorderColor(TNodeType nt) {
267                 String borderColor = nt.getOtherAttributes().get(QNames.QNAME_BORDER_COLOR);
268                 if (borderColor == null) {
269                         borderColor = Util.getColor(nt.getName());
270                 }
271                 return borderColor;
272         }
273         
274         public static String getColor(TRelationshipType rt) {
275                 String color = rt.getOtherAttributes().get(QNames.QNAME_COLOR);
276                 if (color == null) {
277                         color = Util.getColor(rt.getName());
278                 }
279                 return color;
280         }
281         
282         /**
283          * Returns the Properties. If no properties exist, the element is created
284          * 
285          * @return
286          */
287         public static org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties getProperties(TBoundaryDefinitions defs) {
288                 org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties properties = defs.getProperties();
289                 if (properties == null) {
290                         properties = new org.eclipse.winery.model.tosca.TBoundaryDefinitions.Properties();
291                         defs.setProperties(properties);
292                 }
293                 return properties;
294         }
295         
296         /**
297          * Special method to get the name of an extensible element as the TOSCA
298          * specification does not have a separate super type for elements with a
299          * name
300          * 
301          * {@link
302          * org.eclipse.winery.common.Util.instanceSupportsNameAttribute(Class<?
303          * extends TOSCAComponentId>)} is related
304          * 
305          * @param e the extensible element offering a name attribute (besides an id
306          *            attribute)
307          * @return the name of the extensible element
308          * @throws IllegalStateException if e does not offer the method "getName"
309          */
310         public static String getName(TExtensibleElements e) {
311                 Method method;
312                 Object res;
313                 try {
314                         method = e.getClass().getMethod("getName");
315                         res = method.invoke(e);
316                 } catch (Exception ex) {
317                         throw new IllegalStateException(ex);
318                 }
319                 return (String) res;
320         }
321         
322         /**
323          * Returns the name of the given element. If the name does not exist or is
324          * empty, the id is returned
325          * 
326          * {@see getName}
327          * 
328          * @return the name if there is a name field, if not, the id is returned. In
329          *         case there is a Name field,
330          */
331         public static String getNameWithIdFallBack(TExtensibleElements ci) {
332                 Method method;
333                 String res = null;
334                 try {
335                         method = ci.getClass().getMethod("getName");
336                         res = (String) method.invoke(ci);
337                 } catch (Exception e) {
338                 }
339                 if (StringUtils.isEmpty(res)) {
340                         try {
341                                 method = ci.getClass().getMethod("getId");
342                                 res = (String) method.invoke(ci);
343                         } catch (Exception e2) {
344                                 throw new IllegalStateException(e2);
345                         }
346                 }
347                 return res;
348         }
349         
350         /**
351          * Special method to set the name of an extensible element as the TOSCA
352          * specification does not have a separate super type for elements with a
353          * name
354          * 
355          * @param e the extensible element offering a name attribute (besides an id
356          *            attribute)
357          * @param name the new name
358          * @throws IllegalStateException if e does not offer the method "getName"
359          */
360         public static void setName(TExtensibleElements e, String name) {
361                 Method method;
362                 try {
363                         method = e.getClass().getMethod("setName", String.class);
364                         method.invoke(e, name);
365                 } catch (Exception ex) {
366                         throw new IllegalStateException(ex);
367                 }
368         }
369         
370         public static boolean allRequiredFieldsNonNull(WinerysPropertiesDefinition wpd) {
371                 boolean valid = wpd.getNamespace() != null;
372                 valid = valid && (wpd.getElementName() != null);
373                 if (valid) {
374                         PropertyDefinitionKVList propertyDefinitionKVList = wpd.getPropertyDefinitionKVList();
375                         valid = (propertyDefinitionKVList != null);
376                         if (valid) {
377                                 for (PropertyDefinitionKV def : propertyDefinitionKVList) {
378                                         valid = valid && (def.getKey() != null);
379                                         valid = valid && (def.getType() != null);
380                                 }
381                         }
382                 }
383                 return valid;
384         }
385         
386         /**
387          * @return null if no explicit left is set
388          */
389         public static String getLeft(TNodeTemplate nodeTemplate) {
390                 Map<QName, String> otherAttributes = nodeTemplate.getOtherAttributes();
391                 String left = otherAttributes.get(new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "x"));
392                 return left;
393         }
394         
395         /**
396          * @return null if no explicit left is set
397          */
398         public static String getTop(TNodeTemplate nodeTemplate) {
399                 Map<QName, String> otherAttributes = nodeTemplate.getOtherAttributes();
400                 String top = otherAttributes.get(new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "y"));
401                 return top;
402         }
403         
404         /**
405          * locates targetObjectRef inside a topology template
406          * 
407          * @param topologyTemplate the topology template to search in
408          * @param targetObjectRef the object ref as String
409          * 
410          * @return null if not found, otherwise the entity template in the topology
411          */
412         public static TEntityTemplate findNodeTemplateOrRequirementOfNodeTemplateOrCapabilityOfNodeTemplateOrRelationshipTemplate(TTopologyTemplate topologyTemplate, String targetObjectRef) {
413                 // We cannot use XMLs id pointing capabilities as we work on the Java model
414                 // Other option: modify the stored XML directly. This is more error prune than walking through the whole topology
415                 for (TEntityTemplate t : topologyTemplate.getNodeTemplateOrRelationshipTemplate()) {
416                         if (t instanceof TNodeTemplate) {
417                                 if (t.getId().equals(targetObjectRef)) {
418                                         return t;
419                                 }
420                                 TNodeTemplate nt = (TNodeTemplate) t;
421                                 
422                                 Requirements requirements = nt.getRequirements();
423                                 if (requirements != null) {
424                                         for (TRequirement req : requirements.getRequirement()) {
425                                                 if (req.getId().equals(targetObjectRef)) {
426                                                         return req;
427                                                 }
428                                         }
429                                 }
430                                 
431                                 Capabilities capabilities = nt.getCapabilities();
432                                 if (capabilities != null) {
433                                         for (TCapability cap : capabilities.getCapability()) {
434                                                 if (cap.getId().equals(targetObjectRef)) {
435                                                         return cap;
436                                                 }
437                                         }
438                                 }
439                                 
440                         } else {
441                                 assert (t instanceof TRelationshipTemplate);
442                                 if (t.getId().equals(targetObjectRef)) {
443                                         return t;
444                                 }
445                         }
446                 }
447                 
448                 // no return hit inside the loop: nothing was found
449                 return null;
450         }
451         
452         /**
453          * Returns the id of the given element
454          * 
455          * The TOSCA specification does NOT always put an id field. In the case of
456          * EntityTypes and EntityTypeImplementations, there is no id, but a name
457          * field
458          * 
459          * This method abstracts from that fact.
460          */
461         public static String getId(TExtensibleElements ci) {
462                 Method method;
463                 Object res;
464                 try {
465                         method = ci.getClass().getMethod("getId");
466                         res = method.invoke(ci);
467                 } catch (Exception e) {
468                         // If no "getId" method is there, we try "getName"
469                         try {
470                                 method = ci.getClass().getMethod("getName");
471                                 res = method.invoke(ci);
472                         } catch (Exception e2) {
473                                 throw new IllegalStateException(e2);
474                         }
475                 }
476                 return (String) res;
477         }
478         
479         /**
480          * Resolves a given id as requirement in the given ServiceTemplate
481          * 
482          * @return null if not found
483          */
484         public static TRequirement resolveRequirement(TServiceTemplate serviceTemplate, String reference) {
485                 TRequirement resolved = null;
486                 for (TEntityTemplate tmpl : serviceTemplate.getTopologyTemplate().getNodeTemplateOrRelationshipTemplate()) {
487                         if (tmpl instanceof TNodeTemplate) {
488                                 TNodeTemplate n = (TNodeTemplate) tmpl;
489                                 Requirements requirements = n.getRequirements();
490                                 if (requirements != null) {
491                                         for (TRequirement req : n.getRequirements().getRequirement()) {
492                                                 if (req.getId().equals(reference)) {
493                                                         resolved = req;
494                                                 }
495                                         }
496                                 }
497                         }
498                 }
499                 return resolved;
500         }
501         
502         public static TCapability resolveCapability(TServiceTemplate serviceTemplate, String reference) {
503                 TCapability resolved = null;
504                 for (TEntityTemplate tmpl : serviceTemplate.getTopologyTemplate().getNodeTemplateOrRelationshipTemplate()) {
505                         if (tmpl instanceof TNodeTemplate) {
506                                 TNodeTemplate n = (TNodeTemplate) tmpl;
507                                 Capabilities capabilities = n.getCapabilities();
508                                 if (capabilities != null) {
509                                         for (TCapability cap : n.getCapabilities().getCapability()) {
510                                                 if (cap.getId().equals(reference)) {
511                                                         resolved = cap;
512                                                 }
513                                         }
514                                 }
515                         }
516                 }
517                 return resolved;
518         }
519         
520         public static TNodeTemplate resolveNodeTemplate(TServiceTemplate serviceTemplate, String reference) {
521                 TNodeTemplate resolved = null;
522                 for (TEntityTemplate tmpl : serviceTemplate.getTopologyTemplate().getNodeTemplateOrRelationshipTemplate()) {
523                         if (tmpl instanceof TNodeTemplate) {
524                                 TNodeTemplate n = (TNodeTemplate) tmpl;
525                                 if (n.getId().equals(reference)) {
526                                         resolved = n;
527                                 }
528                         }
529                 }
530                 return resolved;
531         }
532         
533         public static TRelationshipTemplate resolveRelationshipTemplate(TServiceTemplate serviceTemplate, String reference) {
534                 TRelationshipTemplate resolved = null;
535                 for (TEntityTemplate tmpl : serviceTemplate.getTopologyTemplate().getNodeTemplateOrRelationshipTemplate()) {
536                         if (tmpl instanceof TRelationshipTemplate) {
537                                 TRelationshipTemplate n = (TRelationshipTemplate) tmpl;
538                                 if (n.getId().equals(reference)) {
539                                         resolved = n;
540                                 }
541                         }
542                 }
543                 return resolved;
544         }
545         
546         public static TPlan resolvePlan(TServiceTemplate serviceTemplate, String reference) {
547                 TPlan resolved = null;
548                 TPlans plans = serviceTemplate.getPlans();
549                 if (plans == null) {
550                         return null;
551                 }
552                 for (TPlan p : plans.getPlan()) {
553                         if (p.getId().equals(reference)) {
554                                 resolved = p;
555                         }
556                 }
557                 return resolved;
558         }
559
560         /**
561          * Sets the x coordinate of a {@link TNodeTemplate}.
562          *
563          * @param nodeTemplate
564          *                       the nodeTemplate to be altered
565          * @param coordinate
566          *                       the value of the coordinate to be set
567          * @return
568          *                       the altered {@link TNodeTemplate}
569          */
570         public static TNodeTemplate setLeft(TNodeTemplate nodeTemplate, String coordinate) {
571
572                 Map<QName, String> otherNodeTemplateAttributes = nodeTemplate.getOtherAttributes();
573                 otherNodeTemplateAttributes.put(new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "x"), coordinate);
574
575                 return nodeTemplate;
576         }
577
578         /**
579          * Sets the y coordinate of a {@link TNodeTemplate}.
580          *
581          * @param nodeTemplate
582          *                       the nodeTemplate to be altered
583          * @param coordinate
584          *                       the value of the coordinate to be set
585          * @return
586          *                       the altered {@link TNodeTemplate}
587          */
588         public static TNodeTemplate setTop(TNodeTemplate nodeTemplate, String coordinate) {
589
590                 Map<QName, String> otherNodeTemplateAttributes = nodeTemplate.getOtherAttributes();
591                 otherNodeTemplateAttributes.put(new QName(Namespaces.TOSCA_WINERY_EXTENSIONS_NAMESPACE, "y"), coordinate);
592
593                 return nodeTemplate;
594
595         }
596
597         /**
598          * This method instantiates a {@link TNodeTemplate} for a given {@link TNodeType}.
599          *
600          * @param nodeType
601          *            the {@link TNodeType} used for the {@link TNodeTemplate} instantiation.
602          *
603          * @return the instantiated {@link TNodeTemplate}
604          */
605         public static TNodeTemplate instantiateNodeTemplate(TNodeType nodeType) {
606
607                 TNodeTemplate nodeTemplate = new TNodeTemplate();
608
609                 nodeTemplate.setId(UUID.randomUUID().toString());
610                 nodeTemplate.setName(nodeType.getName());
611                 nodeTemplate.setType(new QName(nodeType.getTargetNamespace(), nodeType.getName()));
612
613                 // add capabilities to the NodeTemplate
614                 if (nodeType.getCapabilityDefinitions() != null) {
615                         for (TCapabilityDefinition cd : nodeType.getCapabilityDefinitions().getCapabilityDefinition()) {
616                                 TCapability capa = new TCapability();
617                                 capa.setId(UUID.randomUUID().toString());
618                                 capa.setName(cd.getCapabilityType().getLocalPart());
619                                 capa.setType(new QName(cd.getCapabilityType().getNamespaceURI(), cd.getCapabilityType().getLocalPart()));
620                                 nodeTemplate.setCapabilities(new Capabilities());
621                                 nodeTemplate.getCapabilities().getCapability().add(capa);
622                         }
623                 }
624
625                 // add requirements
626                 if (nodeType.getRequirementDefinitions() != null && nodeType.getRequirementDefinitions().getRequirementDefinition() != null) {
627                         Requirements requirementsNode = new Requirements();
628                         nodeTemplate.setRequirements(requirementsNode);
629                         for (TRequirementDefinition definition : nodeType.getRequirementDefinitions().getRequirementDefinition()) {
630                                 TRequirement newRequirement = new TRequirement();
631                                 newRequirement.setName(definition.getName());
632                                 newRequirement.setId(definition.getName());
633                                 newRequirement.setType(definition.getRequirementType());
634                                 nodeTemplate.getRequirements().getRequirement().add(newRequirement);
635                         }
636                 }
637
638                 return nodeTemplate;
639         }
640
641         /**
642          * This method instantiates a {@link TRelationshipTemplate} for a given {@link TRelationshipType}.
643          *
644          * @param nodeType
645          *            the {@link TRelationshipType} used for the {@link TRelationshipTemplate} instantiation.
646          * @param sourceNodeTemplate
647          *            the source {@link TNodeTemplate} of the connection
648          * @param targetNodeTemplate
649          *            the target {@link TNodeTemplate} of the connection
650          *
651          * @return the instantiated {@link TRelationshipTemplate}
652          */
653         public static TRelationshipTemplate instantiateRelationshipTemplate(TRelationshipType relationshipType, TNodeTemplate sourceNodeTemplate, TNodeTemplate targetNodeTemplate) {
654
655                 TRelationshipTemplate relationshipTemplate = new TRelationshipTemplate();
656                 relationshipTemplate.setId(UUID.randomUUID().toString());
657                 relationshipTemplate.setName(relationshipType.getName());
658                 relationshipTemplate.setType(new QName(relationshipType.getTargetNamespace(), relationshipType.getName()));
659
660                 // connect the NodeTemplates
661                 SourceElement source = new SourceElement();
662                 source.setRef(sourceNodeTemplate);
663                 relationshipTemplate.setSourceElement(source);
664                 TargetElement target = new TargetElement();
665                 target.setRef(targetNodeTemplate);
666                 relationshipTemplate.setTargetElement(target);
667
668                 return relationshipTemplate;
669         }
670 }