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 / admin / types / AbstractTypesManager.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.admin.types;
13
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.SortedSet;
18 import java.util.TreeSet;
19
20 import javax.ws.rs.DELETE;
21 import javax.ws.rs.FormParam;
22 import javax.ws.rs.GET;
23 import javax.ws.rs.POST;
24 import javax.ws.rs.Path;
25 import javax.ws.rs.PathParam;
26 import javax.ws.rs.Produces;
27 import javax.ws.rs.QueryParam;
28 import javax.ws.rs.core.Context;
29 import javax.ws.rs.core.MediaType;
30 import javax.ws.rs.core.Response;
31 import javax.ws.rs.core.Response.Status;
32 import javax.ws.rs.core.UriInfo;
33
34 import org.apache.commons.lang3.StringUtils;
35 import org.eclipse.winery.common.Util;
36 import org.eclipse.winery.repository.datatypes.TypeWithShortName;
37 import org.eclipse.winery.repository.datatypes.ids.admin.TypesId;
38 import org.eclipse.winery.repository.datatypes.select2.Select2DataItem;
39 import org.eclipse.winery.repository.resources.admin.AbstractAdminResource;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 import com.sun.jersey.api.view.Viewable;
44
45 /**
46  * Handles longname/shortname by using properties
47  * 
48  * FIXME: This class does NOT support dynamic reloading of the underlying
49  * Configuration instance
50  * 
51  */
52 public abstract class AbstractTypesManager extends AbstractAdminResource {
53         
54         @Context
55         private UriInfo uriInfo;
56         
57         protected static final Logger logger = LoggerFactory.getLogger(AbstractTypesManager.class);
58         
59         // hashes from a long type string to the type object holding complete type data
60         private final HashMap<String, TypeWithShortName> hashTypeStringToType;
61         
62         
63         public AbstractTypesManager(TypesId id) {
64                 super(id);
65                 // now, this.configuration is filled with stored data
66                 
67                 // copy over information from configuration to internal data structure
68                 this.hashTypeStringToType = new HashMap<String, TypeWithShortName>();
69                 Iterator<String> keys = this.configuration.getKeys();
70                 while (keys.hasNext()) {
71                         String key = keys.next();
72                         String value = this.configuration.getString(key);
73                         TypeWithShortName typeInfo = new TypeWithShortName(key, value);
74                         this.hashTypeStringToType.put(key, typeInfo);
75                 }
76         }
77         
78         protected void addData(String longName, String shortName) {
79                 TypeWithShortName t = new TypeWithShortName(longName, shortName);
80                 this.addData(t);
81         }
82         
83         /**
84          * Adds data to the internal data structure WITHOUT persisting it
85          * 
86          * More or less a quick hack to enable adding default types without
87          * persisting them in the storage
88          * 
89          * @param t the type to add
90          */
91         private void addData(TypeWithShortName t) {
92                 this.hashTypeStringToType.put(t.getType(), t);
93         }
94         
95         public synchronized void addTypeWithShortName(TypeWithShortName type) {
96                 this.addData(type);
97                 this.configuration.setProperty(type.getType(), type.getShortName());
98         }
99         
100         /**
101          * Removes a type. Will not remove a type added by "addData"
102          */
103         @DELETE
104         @Path("{type}")
105         public Response removeTypeWithResponse(@PathParam("type") String type) {
106                 type = Util.URLdecode(type);
107                 if (this.configuration.containsKey(type)) {
108                         this.hashTypeStringToType.remove(type);
109                         this.configuration.clearProperty(type);
110                         return Response.noContent().build();
111                 } else if (this.hashTypeStringToType.containsKey(type)) {
112                         // predefined types may not be deleted
113                         // this branch is hit at types added via addData (e.g., predefined plantypes)
114                         return Response.status(Status.FORBIDDEN).build();
115                 } else {
116                         return Response.status(Status.NOT_FOUND).build();
117                 }
118         }
119         
120         /**
121          * Returns a sorted list of all available types
122          */
123         public Collection<TypeWithShortName> getTypes() {
124                 Collection<TypeWithShortName> res = new TreeSet<TypeWithShortName>(this.hashTypeStringToType.values());
125                 return res;
126         }
127         
128         @GET
129         @Produces(MediaType.APPLICATION_JSON)
130         public Object getTypesAsJSONArrayList(@QueryParam("select2") String select2) {
131                 if (select2 == null) {
132                         return this.getTypes();
133                 } else {
134                         // select2 mode
135                         SortedSet<Select2DataItem> res = new TreeSet<>();
136                         for (TypeWithShortName t : this.getTypes()) {
137                                 Select2DataItem item = new Select2DataItem(t.getType(), t.getShortName());
138                                 res.add(item);
139                         }
140                         return res;
141                 }
142         }
143         
144         /**
145          * <b>SIDEEFFECT:</b> If there currently isn't any short type name, it is
146          * created
147          */
148         public TypeWithShortName getTypeWithShortName(String typeString) {
149                 TypeWithShortName t = this.hashTypeStringToType.get(typeString);
150                 if (t == null) {
151                         String shortName = this.getShortName(typeString);
152                         t = new TypeWithShortName(typeString, shortName);
153                         this.addTypeWithShortName(t);
154                 }
155                 return t;
156         }
157         
158         /**
159          * <b>SIDEEFFECT:</b> If there currently isn't any short type name, it is
160          * created
161          */
162         public String getShortName(String typeString) {
163                 TypeWithShortName type = this.hashTypeStringToType.get(typeString);
164                 String res;
165                 if (type == null) {
166                         // happens if artifact type is not registered in artifacttypes.list
167                         // (DATAFILENAME)
168                         res = typeString;
169                 } else {
170                         res = type.getShortName();
171                 }
172                 return res;
173         }
174         
175         @GET
176         @Produces(MediaType.TEXT_HTML)
177         public Viewable getHTML(@Context UriInfo uriInfo) {
178                 this.uriInfo = uriInfo;
179                 return new Viewable("/jsp/admin/types/types.jsp", this);
180         }
181         
182         @POST
183         public Response updateTypeMapping(@FormParam("shortname") String shortName, @FormParam("type") String type) {
184                 if (StringUtils.isEmpty(shortName)) {
185                         return Response.status(Status.BAD_REQUEST).entity("shortName has to be given").build();
186                 }
187                 if (StringUtils.isEmpty(type)) {
188                         return Response.status(Status.BAD_REQUEST).entity("type has to be given").build();
189                 }
190                 shortName = Util.URLdecode(shortName);
191                 type = Util.URLdecode(type);
192                 TypeWithShortName tws = new TypeWithShortName(type, shortName);
193                 this.addTypeWithShortName(tws);
194                 return Response.noContent().build();
195         }
196         
197         /**
198          * Required by types.jsp
199          */
200         public String getURL() {
201                 return this.uriInfo.getAbsolutePath().toString();
202         }
203         
204 }