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
10 * Oliver Kopp - initial API and implementation
11 *******************************************************************************/
12 package org.eclipse.winery.repository.resources.entitytypes.properties;
14 import java.util.ArrayList;
15 import java.util.List;
17 import javax.ws.rs.Consumes;
18 import javax.ws.rs.DELETE;
19 import javax.ws.rs.FormParam;
20 import javax.ws.rs.GET;
21 import javax.ws.rs.POST;
22 import javax.ws.rs.Path;
23 import javax.ws.rs.Produces;
24 import javax.ws.rs.core.MediaType;
25 import javax.ws.rs.core.Response;
26 import javax.ws.rs.core.Response.Status;
27 import javax.xml.namespace.QName;
29 import org.apache.commons.lang3.StringUtils;
30 import org.eclipse.winery.common.ModelUtilities;
31 import org.eclipse.winery.common.constants.MimeTypes;
32 import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition;
33 import org.eclipse.winery.model.tosca.TEntityType;
34 import org.eclipse.winery.model.tosca.TEntityType.PropertiesDefinition;
35 import org.eclipse.winery.repository.backend.BackendUtils;
36 import org.eclipse.winery.repository.resources.EntityTypeResource;
37 import org.eclipse.winery.repository.resources.entitytypes.properties.winery.WinerysPropertiesDefinitionResource;
38 import org.restdoc.annotations.RestDoc;
39 import org.restdoc.annotations.RestDocParam;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 import com.sun.jersey.api.view.Viewable;
48 * <li>TOSCA conforming properties definition (XML element / XML schema / none)</li>
49 * <li>Winery's KV properties (in the subresource "winery")</li>
52 * This class does not have "KV" in its name, because it models
53 * {@link TEntityType.PropertiesDefinition}
55 public class PropertiesDefinitionResource {
57 private static final Logger logger = LoggerFactory.getLogger(PropertiesDefinitionResource.class);
59 // We hold a copy of super.res as we work on the type EntityTypeResource instead of AbstractComponentInstanceResource
60 private final EntityTypeResource parentRes;
62 // we assume that this class is created at each request
63 // therefore, we can have "wpd" final
64 private final WinerysPropertiesDefinition wpd;
67 public PropertiesDefinitionResource(EntityTypeResource res) {
69 this.wpd = ModelUtilities.getWinerysPropertiesDefinition(res.getEntityType());
73 @Produces(MediaType.TEXT_HTML)
74 public Viewable getHTML() {
75 return new Viewable("/jsp/entitytypes/properties/propertiesDefinition.jsp", new JSPData(this, this.wpd));
78 public TEntityType getEntityType() {
79 return this.parentRes.getEntityType();
83 public WinerysPropertiesDefinitionResource getWinerysPropertiesDefinitionResource() {
84 // this.wpd is null if there is no winery definition exisitin. The subresource handles that case, too
85 return new WinerysPropertiesDefinitionResource(this.parentRes, this.wpd);
89 public Response clearPropertiesDefinition() {
90 this.getEntityType().setPropertiesDefinition(null);
91 ModelUtilities.removeWinerysPropertiesDefinition(this.getEntityType());
92 return BackendUtils.persist(this.parentRes);
95 public boolean getIsWineryKeyValueProperties() {
96 return (this.wpd != null);
100 @Produces(MimeTypes.MIMETYPE_XSD)
101 public Response getXSD() {
102 if (this.getIsWineryKeyValueProperties()) {
103 return Response.ok().entity(ModelUtilities.getWinerysPropertiesDefinitionXSDAsDocument(this.wpd)).build();
105 // not yet implemented
106 // We would have to check the imports in the repo for the defined property
107 // This also has to be similarly done at the export to determine the right imports
108 return Response.status(Status.NOT_FOUND).build();
113 @RestDoc(methodDescription = "We provide the XSD at . and at ./xsd/ to enable simple quering in the browser without the hazzle of setting the correct mime type.")
115 @Produces(MimeTypes.MIMETYPE_XSD)
116 public Response getXSDAtSubResource() {
117 return this.getXSD();
122 @RestDoc(methodDescription="Updates/creates a property based on XSD element or XML schema.")
123 @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
124 @Produces(MediaType.TEXT_PLAIN)
125 public Response onPost(
126 @FormParam("name") @RestDocParam(description="Either xsdelement or xsdtype. 'name' comes from x-editable, which uses that as field name") String name,
127 @FormParam("value") @RestDocParam(description="The qname") String value) {
129 if (StringUtils.isEmpty(name)) {
130 return Response.status(Status.BAD_REQUEST).entity("You have to provide a key/type or a name/value pair").build();
132 if (StringUtils.isEmpty(value)) {
133 return Response.status(Status.BAD_REQUEST).entity("If a name is provided, a value has also to be provided").build();
136 // first of all, remove Winery's Properties definition (if it exists)
137 ModelUtilities.removeWinerysPropertiesDefinition(this.getEntityType());
139 QName qname = QName.valueOf(value);
141 // replace old properties definition by new one
142 PropertiesDefinition def = new PropertiesDefinition();
143 if (name.equals("xsdtype")) {
145 } else if (name.equals("xsdelement")) {
146 def.setElement(qname);
148 return Response.status(Status.BAD_REQUEST).entity("Invalid name. Choose xsdelement or xsdtype").build();
150 this.getEntityType().setPropertiesDefinition(def);
151 List<String> errors = new ArrayList<>();
152 BackendUtils.deriveWPD(this.getEntityType(), errors);
153 // currently the errors are just logged
154 for (String error : errors) {
155 PropertiesDefinitionResource.logger.debug(error);
157 return BackendUtils.persist(this.parentRes);