View Javadoc

1   /*
2    * Copyright (C) 2017-2019 Centre National d'Etudes Spatiales (CNES).
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 3.0 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17   * MA 02110-1301  USA
18   */
19  package fr.cnes.doi.resource.admin;
20  
21  import java.util.Map;
22  
23  import org.apache.logging.log4j.Level;
24  import org.apache.logging.log4j.Logger;
25  import org.restlet.data.Form;
26  import org.restlet.data.MediaType;
27  import org.restlet.data.Method;
28  import org.restlet.data.Status;
29  import org.restlet.ext.wadl.DocumentationInfo;
30  import org.restlet.ext.wadl.MethodInfo;
31  import org.restlet.ext.wadl.ParameterStyle;
32  import org.restlet.ext.wadl.RepresentationInfo;
33  import org.restlet.representation.Representation;
34  import org.restlet.representation.StringRepresentation;
35  import org.restlet.resource.Get;
36  import org.restlet.resource.Post;
37  import org.restlet.resource.ResourceException;
38  
39  import fr.cnes.doi.application.AdminApplication;
40  import fr.cnes.doi.db.model.DOIProject;
41  import fr.cnes.doi.exception.DOIDbException;
42  import fr.cnes.doi.resource.AbstractResource;
43  import fr.cnes.doi.utils.UniqueProjectName;
44  import fr.cnes.doi.utils.spec.Requirement;
45  import java.util.List;
46  import java.util.stream.Collectors;
47  
48  /**
49   * Provides a unique identifier to the project. This identifier is used as part
50   * of the DOI name.
51   *
52   * @author Jean-Christophe Malapert (jean-christophe.malapert@cnes.fr)
53   */
54  public class SuffixProjectsResource extends AbstractResource {
55  
56      /**
57       * Parameter for the project name {@value #PROJECT_NAME_PARAMETER}. This
58       * parameter is send to create an identifier for the project.
59       */
60      public static final String PROJECT_NAME_PARAMETER = "projectName";
61      /**
62       * Number of digits ({@value #NB_DIGITS}) in which the suffix project is
63       * encoded.
64       */
65      public static final int NB_DIGITS = 6;
66  
67      /**
68       * Query parameter for user {@value #USER_PARAMETER}.
69       */
70      public static final String USER_PARAMETER = "user";
71  
72      /**
73       * Logger.
74       */
75      private volatile Logger LOG;
76  
77      /**
78       * The user name
79       */
80      private volatile String userName;
81  
82      /**
83       * Set-up method that can be overridden in order to initialize the state of
84       * the resource.
85       *
86       * @throws ResourceException - if a problem happens
87       */
88      @Override
89      protected void doInit() throws ResourceException {
90          super.doInit();
91          final AdminApplication app = (AdminApplication) getApplication();
92          LOG = app.getLog();
93          LOG.traceEntry();
94  
95          this.userName = getQueryValue(USER_PARAMETER);
96          LOG.debug("USER Parameter : " + this.userName);
97  
98          setDescription("This resource handles the project suffix in the DOI name");
99          LOG.traceExit();
100     }
101 
102     /**
103      * Returns the list of projects as Json or xml format.
104      *
105      * @return the list of projects as Json or xml format
106      */
107     @Requirement(reqId = Requirement.DOI_SRV_140, reqName = Requirement.DOI_SRV_140_NAME)
108     @Get("json|xml")
109     public Map<String, Integer> getProjectsNameAsJson() {
110         LOG.traceEntry();
111         try {
112             final List<DOIProject> projects;
113             if (this.userName == null || this.userName.isEmpty()) {
114                 projects = UniqueProjectName.getInstance().getProjects();
115             } else {
116                 projects = UniqueProjectName.getInstance().getProjectsFromUser(this.userName);
117             }
118             return projects.stream().collect(
119                     Collectors.toMap(DOIProject::getProjectname, DOIProject::getSuffix));
120         } catch (DOIDbException ex) {
121             throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST,
122                     this.userName + " already exists");
123         }
124     }
125 
126     /**
127      * Creates a suffix projet based on the project name. The project name is
128      * passed as parameter( {@link #PROJECT_NAME_PARAMETER} ) in the mediaForm.
129      *
130      * When a project suffix is created, a role with the same name is also
131      * automatically created.
132      *
133      * @param mediaForm submitted form
134      * @return A text representation of the encoded project name
135      */
136     @Requirement(reqId = Requirement.DOI_SRV_130, reqName = Requirement.DOI_SRV_130_NAME)
137     @Post
138     public Representation createProject(final Form mediaForm) {
139         LOG.traceEntry("Parameters\n\tmediaForm : {}", mediaForm);
140         checkInputs(mediaForm);
141         final String projectName = mediaForm.getFirstValue(PROJECT_NAME_PARAMETER);
142         try {
143             final int digits = UniqueProjectName.getInstance().getShortName(projectName, NB_DIGITS);
144             return LOG.traceExit(new StringRepresentation(String.valueOf(digits)));
145         } catch (DOIDbException ex) {
146             throw LOG.throwing(new ResourceException(
147                     Status.CLIENT_ERROR_BAD_REQUEST, projectName + " already exists !"));
148         }
149     }
150 
151     /**
152      * Tests if the {@link #PROJECT_NAME_PARAMETER} is set.
153      *
154      * @param mediaForm the parameters
155      * @throws ResourceException - if PROJECT_NAME_PARAMETER is not set
156      */
157     private void checkInputs(final Form mediaForm) throws ResourceException {
158         LOG.traceEntry("Parameters\n\tmediaForm : {}", mediaForm);
159         if (isValueNotExist(mediaForm, PROJECT_NAME_PARAMETER)) {
160             throw LOG.throwing(Level.ERROR, new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST,
161                     PROJECT_NAME_PARAMETER + " parameter must be set"));
162         }
163         LOG.debug("The form is valid");
164         LOG.traceExit();
165     }
166 
167     /**
168      * projects representation
169      *
170      * @return Wadl representation for projects
171      */
172     @Requirement(reqId = Requirement.DOI_DOC_010, reqName = Requirement.DOI_DOC_010_NAME)
173     private RepresentationInfo projectsRepresentation() {
174         final RepresentationInfo repInfo = new RepresentationInfo();
175         repInfo.setMediaType(MediaType.APPLICATION_XML);
176         final DocumentationInfo docInfo = new DocumentationInfo();
177         docInfo.setTitle("Projects Representation");
178         docInfo.setTextContent("The representation contains informations about all projects.");
179         repInfo.setDocumentation(docInfo);
180         return repInfo;
181     }
182 
183     /**
184      * Describes a GET method.
185      *
186      * @param info method information
187      */
188     @Requirement(reqId = Requirement.DOI_DOC_010, reqName = Requirement.DOI_DOC_010_NAME)
189     @Override
190     protected void describeGet(final MethodInfo info) {
191         info.setName(Method.GET);
192         info.setDocumentation("Get information about the created projects");
193         addResponseDocToMethod(info, createResponseDoc(
194                 Status.SUCCESS_OK,
195                 "Operation successful",
196                 projectsRepresentation()
197         ));
198     }
199 
200     /**
201      * Describes a POST method.
202      *
203      * @param info method information
204      */
205     @Requirement(reqId = Requirement.DOI_DOC_010, reqName = Requirement.DOI_DOC_010_NAME)
206     @Override
207     protected void describePost(final MethodInfo info) {
208         info.setName(Method.POST);
209         info.setDocumentation("Creates a project suffix");
210         addRequestDocToMethod(info, createQueryParamDoc(
211                 SuffixProjectsResource.PROJECT_NAME_PARAMETER,
212                 ParameterStyle.MATRIX, "project name", true, "xs:string"));
213         addResponseDocToMethod(info, createResponseDoc(
214                 Status.SUCCESS_OK, "Operation successful", stringRepresentation()));
215     }
216 
217 }