7bc7c73befa904fd5124fe893abb24dc58a97218
[vfc/nfvo/wfengine.git] / winery / org.eclipse.winery.repository / src / main / java / org / eclipse / winery / repository / resources / AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.java
1 /*******************************************************************************
2  * Copyright (c) 2012-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.repository.resources;
13
14 import java.lang.reflect.Method;
15
16 import javax.ws.rs.GET;
17 import javax.ws.rs.PUT;
18 import javax.ws.rs.Path;
19 import javax.ws.rs.core.Response;
20 import javax.ws.rs.core.Response.Status;
21 import javax.xml.namespace.QName;
22
23 import org.eclipse.winery.common.ModelUtilities;
24 import org.eclipse.winery.common.ids.definitions.TOSCAComponentId;
25 import org.eclipse.winery.model.tosca.TBoolean;
26 import org.eclipse.winery.model.tosca.TEntityType.DerivedFrom;
27 import org.eclipse.winery.repository.backend.BackendUtils;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * Models a component instance with name, derived from, abstract, and final <br />
33  * Tags are provided by AbstractComponentInstanceResource
34  * 
35  * This class mirrors
36  * AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinalConfigurationBacked
37  * . We did not include interfaces as the getters are currently only called at
38  * the jsp
39  */
40 public abstract class AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal extends AbstractComponentInstanceResource {
41         
42         private static final Logger logger = LoggerFactory.getLogger(AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.class);
43         
44         
45         protected AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal(TOSCAComponentId id) {
46                 super(id);
47         }
48         
49         /**
50          * @return The associated name of this resource. CSDPR01 foresees a NCName
51          *         name and no ID for an entity type. Therefore, we use the ID as
52          *         unique identification and convert it to a name when a read
53          *         request is put.
54          */
55         @GET
56         @Path("name")
57         public String getName() {
58                 return ModelUtilities.getName(this.getElement());
59         }
60         
61         @PUT
62         @Path("name")
63         public Response putName(String name) {
64                 ModelUtilities.setName(this.getElement(), name);
65                 return BackendUtils.persist(this);
66         }
67         
68         @GET
69         @Path("derivedFrom")
70         public String getDerivedFrom() {
71                 // TOSCA does not introduce a type like WithNameDerivedFromAbstractFinal
72                 // We could enumerate all possible implementing classes
73                 // Or use java reflection, what we're doing now.
74                 Method method;
75                 // We have three different "DerivedFrom", for NodeTypeImplementation and RelationshipTypeImplementation, we have to assign to a different "DerivedFrom"
76                 // This has to be done in the derived resources
77                 DerivedFrom derivedFrom;
78                 try {
79                         method = this.getElement().getClass().getMethod("getDerivedFrom");
80                         derivedFrom = (DerivedFrom) method.invoke(this.getElement());
81                 } catch (ClassCastException e) {
82                         AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Seems that *Implementation is now Definitions backed, but not yet fully implented", e);
83                         throw new IllegalStateException(e);
84                 } catch (Exception e) {
85                         AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Could not get derivedFrom", e);
86                         throw new IllegalStateException(e);
87                 }
88                 if (derivedFrom == null) {
89                         return null;
90                 }
91                 QName typeRef = derivedFrom.getTypeRef();
92                 if (typeRef == null) {
93                         return null;
94                 } else {
95                         return typeRef.toString();
96                 }
97         }
98         
99         @PUT
100         @Path("derivedFrom")
101         public Response putDerivedFrom(String type) {
102                 QName qname = QName.valueOf(type);
103                 
104                 // see getDerivedFrom for verbose comments
105                 Method method;
106                 DerivedFrom derivedFrom = new DerivedFrom();
107                 derivedFrom.setTypeRef(qname);
108                 try {
109                         method = this.getElement().getClass().getMethod("setDerivedFrom", DerivedFrom.class);
110                         method.invoke(this.getElement(), derivedFrom);
111                 } catch (ClassCastException e) {
112                         AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Seems that *Implementation is now Definitions backed, but not yet fully implemented", e);
113                         return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build();
114                 } catch (Exception e) {
115                         AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Could not set derivedFrom", e);
116                         return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build();
117                 }
118                 
119                 return BackendUtils.persist(this);
120         }
121         
122         /**
123          * @param methodName the method to call: getAbstract|getFinal
124          * @return {@inheritDoc}
125          */
126         private String getTBoolean(String methodName) {
127                 // see getDerivedFrom for verbose comments
128                 Method method;
129                 TBoolean tBoolean;
130                 try {
131                         method = this.getElement().getClass().getMethod(methodName);
132                         tBoolean = (TBoolean) method.invoke(this.getElement());
133                 } catch (Exception e) {
134                         AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Could not get boolean " + methodName, e);
135                         throw new IllegalStateException(e);
136                 }
137                 if (tBoolean == null) {
138                         return null;
139                 } else {
140                         return tBoolean.value();
141                 }
142         }
143         
144         /**
145          * @param methodName the method to call: setAbstract|setFinal
146          * @return {@inheritDoc}
147          */
148         private Response putTBoolean(String tBooleanStr, String methodName) {
149                 // see getDerivedFrom for verbose comments
150                 
151                 Method method;
152                 TBoolean tBoolean = TBoolean.fromValue(tBooleanStr);
153                 try {
154                         method = this.getElement().getClass().getMethod(methodName, TBoolean.class);
155                         method.invoke(this.getElement(), tBoolean);
156                 } catch (Exception e) {
157                         AbstractComponentInstanceResourceWithNameDerivedFromAbstractFinal.logger.error("Could not set tBoolean " + methodName, e);
158                         return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build();
159                 }
160                 
161                 return BackendUtils.persist(this);
162         }
163         
164         /**
165          * Method name is not "getAbstract" as ${it.abstract} does not work as
166          * "abstract" is not allowed at that place
167          */
168         @GET
169         @Path("abstract")
170         public String getIsAbstract() {
171                 return this.getTBoolean("getAbstract");
172         }
173         
174         @PUT
175         @Path("abstract")
176         public Response putIsAbstract(String isAbstract) {
177                 return this.putTBoolean(isAbstract, "setAbstract");
178         }
179         
180         @GET
181         @Path("final")
182         public String getIsFinal() {
183                 return this.getTBoolean("getFinal");
184         }
185         
186         @PUT
187         @Path("final")
188         public Response putIsFinal(String isFinal) {
189                 return this.putTBoolean(isFinal, "setFinal");
190         }
191         
192         /**
193          * @return resource managing abstract, final, derivedFrom
194          */
195         @Path("inheritance/")
196         public InheritanceResource getInheritanceManagement() {
197                 return new InheritanceResource(this);
198         }
199         
200 }