Merge "Fix build errors in autorelease full clean build"
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.repository / src / main / java / org / eclipse / winery / repository / resources / entitytemplates / artifacttemplates / ArtifactTemplateResource.java
1 /*******************************************************************************
2  * Copyright (c) 2012-2014 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.repository.resources.entitytemplates.artifacttemplates;
13
14 import java.util.Collection;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.SortedSet;
18
19 import javax.ws.rs.GET;
20 import javax.ws.rs.Path;
21 import javax.ws.rs.Produces;
22 import javax.ws.rs.QueryParam;
23 import javax.ws.rs.core.MediaType;
24 import javax.ws.rs.core.Response;
25 import javax.ws.rs.core.Response.Status;
26 import javax.xml.namespace.QName;
27
28 import org.eclipse.winery.common.RepositoryFileReference;
29 import org.eclipse.winery.common.ids.definitions.ArtifactTemplateId;
30 import org.eclipse.winery.common.ids.definitions.ArtifactTypeId;
31 import org.eclipse.winery.common.ids.definitions.NodeTypeImplementationId;
32 import org.eclipse.winery.common.ids.definitions.RelationshipTypeImplementationId;
33 import org.eclipse.winery.common.ids.definitions.ServiceTemplateId;
34 import org.eclipse.winery.model.tosca.TArtifactReference;
35 import org.eclipse.winery.model.tosca.TArtifactTemplate;
36 import org.eclipse.winery.model.tosca.TArtifactTemplate.ArtifactReferences;
37 import org.eclipse.winery.model.tosca.TDeploymentArtifact;
38 import org.eclipse.winery.model.tosca.TDeploymentArtifacts;
39 import org.eclipse.winery.model.tosca.TEntityTemplate;
40 import org.eclipse.winery.model.tosca.TExtensibleElements;
41 import org.eclipse.winery.model.tosca.TImplementationArtifact;
42 import org.eclipse.winery.model.tosca.TImplementationArtifacts;
43 import org.eclipse.winery.model.tosca.TNodeTemplate;
44 import org.eclipse.winery.model.tosca.TTopologyTemplate;
45 import org.eclipse.winery.repository.Utils;
46 import org.eclipse.winery.repository.backend.BackendUtils;
47 import org.eclipse.winery.repository.backend.Repository;
48 import org.eclipse.winery.repository.datatypes.ids.elements.ArtifactTemplateDirectoryId;
49 import org.eclipse.winery.repository.resources.AbstractComponentInstanceWithReferencesResource;
50 import org.eclipse.winery.repository.resources.AbstractComponentsResource;
51 import org.eclipse.winery.repository.resources.IHasName;
52 import org.eclipse.winery.repository.resources.entitytemplates.IEntityTemplateResource;
53 import org.eclipse.winery.repository.resources.entitytemplates.PropertiesResource;
54 import org.eclipse.winery.repository.resources.entitytemplates.TEntityTemplateResource;
55 import org.eclipse.winery.repository.resources.entitytypeimplementations.nodetypeimplementations.NodeTypeImplementationResource;
56 import org.eclipse.winery.repository.resources.entitytypeimplementations.relationshiptypeimplementations.RelationshipTypeImplementationResource;
57 import org.eclipse.winery.repository.resources.entitytypes.artifacttypes.ArtifactTypeResource;
58 import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource;
59
60 /**
61  * Models an Artifact Template with its artifact references
62  * 
63  * The associated files (through tArtifactReference) are stored directly within
64  * this resource. The element <ArtifactReference> is generated during export
65  * only
66  * 
67  * This class inherits from AbstractComponentInstanceResourceDefinitionsBacked
68  * and not from TEntityTemplateResource<TArtifactTemplate>, because
69  * ArtifactTemplates are directly available under TDefinitions and we need the
70  * generic resource handling
71  */
72
73 public class ArtifactTemplateResource extends AbstractComponentInstanceWithReferencesResource implements IEntityTemplateResource<TArtifactTemplate>, IHasName {
74         
75         private final TEntityTemplateResource<TArtifactTemplate> entityTemplateResource;
76         
77         
78         public ArtifactTemplateResource(ArtifactTemplateId id) {
79                 super(id);
80                 // we provide the minimum requirements for the resource
81                 this.entityTemplateResource = new TEntityTemplateResource<TArtifactTemplate>(null, this.getTArtifactTemplate(), 0, null, this);
82         }
83         
84         /**
85          * @return null if no artifact type resource is defined
86          */
87         public ArtifactTypeResource getAritfactTypeResource() {
88                 ArtifactTypeId atId = new ArtifactTypeId(this.getTArtifactTemplate().getType());
89                 return new ArtifactTypeResource(atId);
90         }
91         
92         private TArtifactTemplate getTArtifactTemplate() {
93                 return (TArtifactTemplate) this.element;
94         }
95         
96         @Override
97         public String getName() {
98                 String name = this.getTArtifactTemplate().getName();
99                 if (name == null) {
100                         return this.getTArtifactTemplate().getId();
101                 } else {
102                         return name;
103                 }
104         }
105         
106         @Override
107         public Response setName(String name) {
108                 this.getTArtifactTemplate().setName(name);
109                 return BackendUtils.persist(this);
110         }
111         
112         @Override
113         protected TExtensibleElements createNewElement() {
114                 return new TArtifactTemplate();
115         }
116         
117         @Override
118         protected void copyIdToFields() {
119                 this.getTArtifactTemplate().setId(this.getId().getXmlId().getDecoded());
120                 // Namespace cannot be set as the namespace is contained in TDefinitions only
121         }
122         
123         /**
124          * {@inheritDoc}
125          */
126         @Override
127         public void synchronizeReferences() {
128                 TArtifactTemplate template = this.getTArtifactTemplate();
129                 
130                 ArtifactTemplateDirectoryId fileDir = new ArtifactTemplateDirectoryId((ArtifactTemplateId) this.id);
131                 SortedSet<RepositoryFileReference> files = Repository.INSTANCE.getContainedFiles(fileDir);
132                 if (files.isEmpty()) {
133                         // clear artifact references
134                         template.setArtifactReferences(null);
135                 } else {
136                         ArtifactReferences artifactReferences = new ArtifactReferences();
137                         template.setArtifactReferences(artifactReferences);
138                         List<TArtifactReference> artRefList = artifactReferences.getArtifactReference();
139                         for (RepositoryFileReference ref : files) {
140                                 // determine path
141                                 // path relative from the root of the CSAR is ok (COS01, line 2663)
142                                 String path = Utils.getURLforPathInsideRepo(BackendUtils.getPathInsideRepo(ref));
143                                 
144                                 // put path into data structure
145                                 // we do not use Inlude/Exclude as we directly reference a concrete file
146                                 TArtifactReference artRef = new TArtifactReference();
147                                 artRef.setReference(path);
148                                 artRefList.add(artRef);
149                         }
150                 }
151         }
152         
153         @Path("files/")
154         public FilesResource getFilesResource() {
155                 ArtifactTemplateDirectoryId fileDir = new ArtifactTemplateDirectoryId((ArtifactTemplateId) this.id);
156                 return new FilesResource(fileDir);
157         }
158         
159         /***********************************************************************
160          * "inheritance" from TEntityTemplateResource<TArtifactTemplate> *
161          * 
162          * Offering all methods of TEntityTemplateResource<TArtifactTemplate> and
163          * forwarding it to our private instance of it
164          */
165         
166         @Override
167         public QName getType() {
168                 return this.entityTemplateResource.getType();
169         }
170         
171         @Override
172         public Response setType(QName type) {
173                 this.entityTemplateResource.setType(type);
174                 return BackendUtils.persist(this);
175         }
176         
177         @Override
178         public Response setType(String typeStr) {
179                 this.entityTemplateResource.setType(typeStr);
180                 return BackendUtils.persist(this);
181         }
182         
183         @Override
184         public PropertiesResource getPropertiesResource() {
185                 return new PropertiesResource(this.getTArtifactTemplate(), this);
186         }
187         
188         int getReferenceCount() {
189                 // We do not use a database, therefore, we have to go through all possibilities pointing to the artifact template
190                 // DAs and IAs point to an artifact template
191                 // DAs are contained in Node Type Implementations and Node Templates
192                 // IAs are contained in Node Type Implementations and Relationship Type Implementations
193                 
194                 int count = 0;
195                 
196                 Collection<TDeploymentArtifact> allDAs = new HashSet<>();
197                 Collection<TImplementationArtifact> allIAs = new HashSet<>();
198                 
199                 // handle Node Type Implementation, which contains DAs and IAs
200                 SortedSet<NodeTypeImplementationId> nodeTypeImplementations = Repository.INSTANCE.getAllTOSCAComponentIds(NodeTypeImplementationId.class);
201                 for (NodeTypeImplementationId ntiId : nodeTypeImplementations) {
202                         NodeTypeImplementationResource ntiRes = (NodeTypeImplementationResource) AbstractComponentsResource.getComponentInstaceResource(ntiId);
203                         TDeploymentArtifacts deploymentArtifacts = ntiRes.getNTI().getDeploymentArtifacts();
204                         if (deploymentArtifacts != null) {
205                                 allDAs.addAll(deploymentArtifacts.getDeploymentArtifact());
206                         }
207                         TImplementationArtifacts implementationArtifacts = ntiRes.getNTI().getImplementationArtifacts();
208                         if (implementationArtifacts != null) {
209                                 allIAs.addAll(implementationArtifacts.getImplementationArtifact());
210                         }
211                 }
212                 
213                 // check all Relationshiptype Implementations for IAs
214                 SortedSet<RelationshipTypeImplementationId> relationshipTypeImplementations = Repository.INSTANCE.getAllTOSCAComponentIds(RelationshipTypeImplementationId.class);
215                 for (RelationshipTypeImplementationId rtiId : relationshipTypeImplementations) {
216                         RelationshipTypeImplementationResource rtiRes = (RelationshipTypeImplementationResource) AbstractComponentsResource.getComponentInstaceResource(rtiId);
217                         TImplementationArtifacts implementationArtifacts = rtiRes.getRTI().getImplementationArtifacts();
218                         if (implementationArtifacts != null) {
219                                 allIAs.addAll(implementationArtifacts.getImplementationArtifact());
220                         }
221                 }
222                 
223                 // check all node templates for DAs
224                 SortedSet<ServiceTemplateId> serviceTemplates = Repository.INSTANCE.getAllTOSCAComponentIds(ServiceTemplateId.class);
225                 for (ServiceTemplateId sid : serviceTemplates) {
226                         ServiceTemplateResource serviceTemplateRes = (ServiceTemplateResource) AbstractComponentsResource.getComponentInstaceResource(sid);
227                         TTopologyTemplate topologyTemplate = serviceTemplateRes.getServiceTemplate().getTopologyTemplate();
228                         if (topologyTemplate != null) {
229                                 List<TEntityTemplate> nodeTemplateOrRelationshipTemplate = topologyTemplate.getNodeTemplateOrRelationshipTemplate();
230                                 for (TEntityTemplate template : nodeTemplateOrRelationshipTemplate) {
231                                         if (template instanceof TNodeTemplate) {
232                                                 TNodeTemplate nodeTemplate = (TNodeTemplate) template;
233                                                 TDeploymentArtifacts deploymentArtifacts = nodeTemplate.getDeploymentArtifacts();
234                                                 if (deploymentArtifacts != null) {
235                                                         allDAs.addAll(deploymentArtifacts.getDeploymentArtifact());
236                                                 }
237                                         }
238                                 }
239                         }
240                 }
241                 
242                 // now we have all DAs and IAs
243                 
244                 QName ourQName = this.getQName();
245                 
246                 // check DAs for artifact templates
247                 for (TDeploymentArtifact da : allDAs) {
248                         QName artifactRef = da.getArtifactRef();
249                         if (ourQName.equals(artifactRef)) {
250                                 count++;
251                         }
252                 }
253                 
254                 // check IAs for artifact templates
255                 for (TImplementationArtifact ia : allIAs) {
256                         QName artifactRef = ia.getArtifactRef();
257                         if (ourQName.equals(artifactRef)) {
258                                 count++;
259                         }
260                 }
261                 
262                 return count;
263         }
264         
265         /**
266          * Query parameter {@code type}:<br />
267          * Returns the type of the artifact template
268          * 
269          * Query parameter {@code referenceCount}:<br />
270          * Determines the number of elements known by the repository which point to
271          * this resource. This method probably can be moved up the type hierarchy.
272          * Currently, it is only required here by the topology modeler.
273          * 
274          * @return the type of the artifact template OR the number of references
275          *         pointing to this resource
276          */
277         @GET
278         @Produces(MediaType.TEXT_PLAIN)
279         public Response getRefereneCount(@QueryParam("referenceCount") String referenceCount, @QueryParam("type") String type) {
280                 if (referenceCount != null) {
281                         String res = Integer.toString(this.getReferenceCount());
282                         return Response.ok().entity(res).build();
283                 } else if (type != null) {
284                         String res = this.getType().toString();
285                         return Response.ok().entity(res).build();
286                 } else {
287                         // we enforce the query parameter to be extensible to other queries
288                         return Response.status(Status.BAD_REQUEST).entity("You have to pass the query parameter referenceCount or type").build();
289                 }
290                 
291         }
292         
293         /* not yet implemented */
294         /*
295         @GET
296         @Produces(MediaType.APPLICATION_JSON)
297         public Response getReferenes(@QueryParam("references") String references) {
298                 if (references== null) {
299                         // we enforce the query parameter to be extensible to other queries
300                         return Response.status(Status.BAD_REQUEST).entity("You have to pass the query parameter references").build();
301                 }
302
303                 String res = Integer.toString(this.getReferenceCount());
304                 return Response.ok().entity(res).build();
305         }
306         */
307         
308 }