0c6936ee474a0bb729104e66303735eda3a27a3f
[vfc/nfvo/wfengine.git] /
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.entitytypes.nodetypes.reqandcapdefs;
13
14 import java.util.Collection;
15 import java.util.List;
16
17 import javax.ws.rs.FormParam;
18 import javax.ws.rs.POST;
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.apache.commons.lang3.StringUtils;
24 import org.eclipse.winery.model.tosca.TCapabilityDefinition;
25 import org.eclipse.winery.model.tosca.TRequirementDefinition;
26 import org.eclipse.winery.repository.backend.BackendUtils;
27 import org.eclipse.winery.repository.resources._support.collections.withid.EntityWithIdCollectionResource;
28 import org.eclipse.winery.repository.resources.entitytypes.nodetypes.NodeTypeResource;
29
30 import com.sun.jersey.api.view.Viewable;
31
32 /**
33  * This superclass has only a few methods as we cannot easily abstract from the
34  * subclasses: We would need Java reflection to invoke "getName" (to get the
35  * subresource). The hope is that this copy'n'paste programming will not
36  * introduce bugs when changing childs
37  * 
38  * We try to abstract from the problems by using generics and reflections
39  * 
40  * @param <ReqDefOrCapDef> TRequirementDefinition or TCapabilityDefinition
41  * @param <ReqDefOrCapDefResource> the resource managing ReqDefOrCapDef
42  */
43 public abstract class RequirementOrCapabilityDefinitionsResource<ReqDefOrCapDefResource extends AbstractReqOrCapDefResource<ReqDefOrCapDef>, ReqDefOrCapDef> extends EntityWithIdCollectionResource<ReqDefOrCapDefResource, ReqDefOrCapDef> {
44         
45         protected final NodeTypeResource res;
46         
47         
48         public RequirementOrCapabilityDefinitionsResource(Class<ReqDefOrCapDefResource> entityResourceTClazz, Class<ReqDefOrCapDef> entityTClazz, List<ReqDefOrCapDef> list, NodeTypeResource res) {
49                 super(entityResourceTClazz, entityTClazz, list, res);
50                 this.res = res;
51         }
52         
53         @Override
54         public abstract Viewable getHTML();
55         
56         /**
57          * @return collection of all available types
58          */
59         public abstract Collection<QName> getAllTypes();
60         
61         @POST
62         // As there is no supertype of TCapabilityType and TRequirementType containing the common attributes, we have to rely on unchecked casts
63         @SuppressWarnings("unchecked")
64         public Response onPost(@FormParam("name") String name, @FormParam("type") String type, @FormParam("lowerbound") String lowerBound, @FormParam("upperbound") String upperbound) {
65                 if (StringUtils.isEmpty(name)) {
66                         return Response.status(Status.BAD_REQUEST).entity("Name has to be provided").build();
67                 }
68                 if (StringUtils.isEmpty(type)) {
69                         return Response.status(Status.BAD_REQUEST).entity("Type has to be provided").build();
70                 }
71                 
72                 int lbound = 1;
73                 if (!StringUtils.isEmpty(lowerBound)) {
74                         try {
75                                 lbound = Integer.parseInt(lowerBound);
76                         } catch (NumberFormatException e) {
77                                 return Response.status(Status.BAD_REQUEST).entity("Bad format of lowerbound: " + e.getMessage()).build();
78                         }
79                 }
80                 
81                 String ubound = "1";
82                 if (!StringUtils.isEmpty(upperbound)) {
83                         ubound = upperbound;
84                 }
85                 
86                 // we also support replacement of existing requirements
87                 // therefore, we loop through the existing requirements
88                 int idx = -1;
89                 boolean found = false;
90                 for (ReqDefOrCapDef d : this.list) {
91                         idx++;
92                         if (this.getId(d).equals(name)) {
93                                 found = true;
94                                 break;
95                         }
96                 }
97                 
98                 QName typeQName = QName.valueOf(type);
99                 // Create object and put type in it
100                 ReqDefOrCapDef def;
101                 if (this instanceof CapabilityDefinitionsResource) {
102                         def = (ReqDefOrCapDef) new TCapabilityDefinition();
103                         ((TCapabilityDefinition) def).setCapabilityType(typeQName);
104                 } else {
105                         assert (this instanceof RequirementDefinitionsResource);
106                         def = (ReqDefOrCapDef) new TRequirementDefinition();
107                         ((TRequirementDefinition) def).setRequirementType(typeQName);
108                 }
109                 
110                 // copy all other data into object
111                 AbstractReqOrCapDefResource.invokeSetter(def, "setName", name);
112                 AbstractReqOrCapDefResource.invokeSetter(def, "setLowerBound", lbound);
113                 AbstractReqOrCapDefResource.invokeSetter(def, "setUpperBound", ubound);
114                 
115                 if (found) {
116                         // replace element
117                         this.list.set(idx, def);
118                 } else {
119                         // add new element
120                         this.list.add(def);
121                 }
122                 
123                 Response r = BackendUtils.persist(this.res);
124                 return r;
125         }
126         
127         @Override
128         public String getId(ReqDefOrCapDef reqDefOrCapDef) {
129                 return AbstractReqOrCapDefResource.getName(reqDefOrCapDef);
130         }
131 }