Add winery source code
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.repository / src / main / java / org / eclipse / winery / repository / resources / servicetemplates / plans / PlanResource.java
1 /*******************************************************************************
2  * Copyright (c) 2012-2015 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.servicetemplates.plans;
13
14 import java.io.IOException;
15 import java.net.URI;
16 import java.util.List;
17
18 import javax.ws.rs.DELETE;
19 import javax.ws.rs.FormParam;
20 import javax.ws.rs.GET;
21 import javax.ws.rs.PUT;
22 import javax.ws.rs.Path;
23 import javax.ws.rs.Produces;
24 import javax.ws.rs.core.Context;
25 import javax.ws.rs.core.MediaType;
26 import javax.ws.rs.core.Response;
27 import javax.ws.rs.core.Response.Status;
28 import javax.ws.rs.core.UriInfo;
29
30 import org.apache.commons.lang3.StringUtils;
31 import org.eclipse.winery.common.Util;
32 import org.eclipse.winery.common.ids.XMLId;
33 import org.eclipse.winery.common.ids.definitions.ServiceTemplateId;
34 import org.eclipse.winery.common.ids.definitions.TOSCAComponentId;
35 import org.eclipse.winery.common.ids.elements.PlanId;
36 import org.eclipse.winery.common.ids.elements.PlansId;
37 import org.eclipse.winery.model.tosca.TPlan;
38 import org.eclipse.winery.model.tosca.TPlan.InputParameters;
39 import org.eclipse.winery.model.tosca.TPlan.OutputParameters;
40 import org.eclipse.winery.repository.Prefs;
41 import org.eclipse.winery.repository.Utils;
42 import org.eclipse.winery.repository.backend.BackendUtils;
43 import org.eclipse.winery.repository.backend.Repository;
44 import org.eclipse.winery.repository.resources.IHasName;
45 import org.eclipse.winery.repository.resources._support.collections.IIdDetermination;
46 import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdResource;
47 import org.eclipse.winery.repository.resources.interfaces.ParametersResource;
48 import org.eclipse.winery.repository.resources.servicetemplates.ServiceTemplateResource;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 /**
53  * Does <em>not</em> implement
54  * {@link org.eclipse.winery.repository.resources.IHasTypeReference}, because
55  * the type of a plan is outside the system of TOSCA.
56  */
57 public class PlanResource extends EntityWithIdResource<TPlan> implements IHasName {
58         
59         private static final Logger logger = LoggerFactory.getLogger(PlanResource.class);
60         
61         
62         public PlanResource(IIdDetermination<TPlan> idDetermination, TPlan o, int idx, List<TPlan> list, ServiceTemplateResource res) {
63                 super(idDetermination, o, idx, list, res);
64         }
65         
66         /**
67          * Ugly hack to get the parent service template resource
68          * 
69          */
70         public ServiceTemplateResource getServiceTemplateResource() {
71                 // Solution proposal 1: Each sub-resource should know its parent service
72                 // template
73                 //
74                 // Solution proposal 2 (Generic solution): Each resource should know its
75                 // parent resource
76                 //
77                 // Does not work when plan is used at as component instance (then,
78                 // serviceTemplateResource is null). In this case, a plan is not associated
79                 // with a service template.
80                 
81                 // we cannot use "((PlanId) id).getParent()" as this "only" returns an
82                 // ID
83                 // we could create a newly resource based on that ID
84                 // However, the parent resource has already been created when the
85                 // PlanResource has been generated:
86                 // Jersey crawls down from the main resource through the service
87                 // template resource to the plan resource
88                 return (ServiceTemplateResource) this.res;
89         }
90         
91         /**
92          * Determines the id of the current resource
93          */
94         private PlanId getId() {
95                 ServiceTemplateId sId = (ServiceTemplateId) this.getServiceTemplateResource().getId();
96                 PlansId psId = new PlansId(sId);
97                 PlanId pId = new PlanId(psId, new XMLId(this.o.getId(), false));
98                 return pId;
99         }
100         
101         @Override
102         @DELETE
103         public Response onDelete() {
104                 Response res = super.onDelete();
105                 if (Utils.isSuccessFulResponse(res)) {
106                         try {
107                                 Repository.INSTANCE.forceDelete(this.getId());
108                         } catch (IOException e) {
109                                 return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Could not remove plan file").build();
110                         }
111                         return BackendUtils.persist(this.res);
112                 } else {
113                         return res;
114                 }
115         }
116         
117         @GET
118         @Produces(MediaType.TEXT_HTML)
119         public Response getHTML(@Context UriInfo uriInfo) {
120                 boolean isBPMN4TOSCA = this.o.getPlanLanguage().equals(org.eclipse.winery.common.constants.Namespaces.URI_BPMN4TOSCA_20);
121                 String bpmn4toscaBaseURL = Prefs.INSTANCE.getBPMN4TOSCABaseURL();
122                 if (isBPMN4TOSCA && (!StringUtils.isEmpty(bpmn4toscaBaseURL))) {
123                         String uri = bpmn4toscaBaseURL;
124                         URI repositoryURI = uriInfo.getBaseUri();
125                         uri += "?repositoryURL=" + Util.URLencode(repositoryURI.toString());
126                         TOSCAComponentId serviceTemplateId = this.getServiceTemplateResource().getId();
127                         uri += "&namespace=" + serviceTemplateId.getNamespace().getEncoded();
128                         uri += "&id=" + serviceTemplateId.getXmlId().getEncoded();
129                         uri += "&plan=" + this.getName();
130                         return Response.temporaryRedirect(Utils.createURI(uri)).build();
131                 } else {
132                         // return Response.ok().entity("No editor plugin found for plan language " + this.o.getPlanLanguage()).build();
133                         URI fileURI = uriInfo.getAbsolutePath().resolve("file");
134                         return Response.seeOther(fileURI).build();
135                 }
136         }
137         
138         @Override
139         public String getName() {
140                 String name = this.o.getName();
141                 if (name == null) {
142                         name = this.o.getId();
143                 }
144                 return name;
145         }
146         
147         @Override
148         public Response setName(@FormParam("value") String name) {
149                 this.o.setName(name);
150                 return BackendUtils.persist(this.res);
151         }
152         
153         @Path("file")
154         public PlanFileResource getPlanFileResource() {
155                 return new PlanFileResource((ServiceTemplateResource) this.res, this.getId(), this.o);
156         }
157         
158         @GET
159         @Path("type")
160         public String getType() {
161                 return this.o.getPlanType();
162         }
163         
164         @PUT
165         @Path("type")
166         public Response setType(@FormParam("type") String type) {
167                 this.o.setPlanType(type);
168                 return BackendUtils.persist(this.res);
169         }
170         
171         @GET
172         @Path("language")
173         public String getLanguage() {
174                 return this.o.getPlanLanguage();
175         }
176         
177         @PUT
178         @Path("language")
179         public Response setLanguage(@FormParam("language") String language) {
180                 this.o.setPlanType(language);
181                 return BackendUtils.persist(this.res);
182         }
183         
184         @Path("inputparameters/")
185         public ParametersResource getInputParametersResource() {
186                 InputParameters inputParameters = this.o.getInputParameters();
187                 if (inputParameters == null) {
188                         inputParameters = new InputParameters();
189                         this.o.setInputParameters(inputParameters);
190                 }
191                 return new ParametersResource(inputParameters.getInputParameter(), this.getServiceTemplateResource());
192         }
193         
194         @Path("outputparameters/")
195         public ParametersResource getOutputParametersResource() {
196                 OutputParameters outputParameters = this.o.getOutputParameters();
197                 if (outputParameters == null) {
198                         outputParameters = new OutputParameters();
199                         this.o.setOutputParameters(outputParameters);
200                 }
201                 return new ParametersResource(outputParameters.getOutputParameter(), this.getServiceTemplateResource());
202         }
203 }