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.mds;
20  
21  import java.util.Arrays;
22  
23  import javax.xml.bind.JAXBException;
24  import javax.xml.bind.ValidationException;
25  
26  import org.apache.logging.log4j.Level;
27  import org.datacite.schema.kernel_4.Resource;
28  import org.restlet.data.MediaType;
29  import org.restlet.data.Method;
30  import org.restlet.data.Status;
31  import org.restlet.ext.wadl.MethodInfo;
32  import org.restlet.ext.wadl.ParameterStyle;
33  import org.restlet.representation.Representation;
34  import org.restlet.resource.Post;
35  import org.xml.sax.SAXException;
36  
37  import fr.cnes.doi.application.DoiMdsApplication.API_MDS;
38  import fr.cnes.doi.exception.ClientMdsException;
39  import fr.cnes.doi.exception.DoiServerException;
40  import fr.cnes.doi.utils.spec.Requirement;
41  
42  /**
43   * Resource to handle a collection of metadata.
44   *
45   * @author Jean-Christophe Malapert (jean-christophe.malapert@cnes.fr)
46   */
47  public class MetadatasResource extends BaseMdsResource {
48  
49      /**
50       * Function of this resource {@value #CREATE_METADATA}.
51       */
52      public static final String CREATE_METADATA = "Create Metadata";
53  
54      /**
55       * Init.
56       *
57       * @throws DoiServerException - if a problem happens
58       */
59      @Override
60      protected void doInit() throws DoiServerException {
61          super.doInit();
62          LOG.traceEntry();
63          setDescription("This resource can create metadata");
64          LOG.traceExit();
65      }
66  
67      /**
68       * Create Metadata for a given DOI. The DOI name is given in the metadata
69       * entity. This request stores new version of metadata and returns a 201
70       * status when the operation is successful.
71       *
72       * @param entity Metadata representation
73       * @return short explanation of status code e.g. CREATED,
74       * HANDLE_ALREADY_EXISTS etc
75       * @throws DoiServerException - if the response is not a success
76       * <ul>
77       * <li>{@link API_MDS#SECURITY_USER_NO_ROLE}</li>
78       * <li>{@link API_MDS#SECURITY_USER_NOT_IN_SELECTED_ROLE}</li>
79       * <li>{@link API_MDS#SECURITY_USER_PERMISSION}</li>
80       * <li>{@link API_MDS#SECURITY_USER_CONFLICT}</li>
81       * <li>{@link API_MDS#DATACITE_PROBLEM}</li>
82       * <li>{@link API_MDS#METADATA_VALIDATION}</li>
83       * <li>{@link API_MDS#NETWORK_PROBLEM}</li>
84       * </ul>
85       */
86      @Requirement(reqId = Requirement.DOI_SRV_010, reqName = Requirement.DOI_SRV_010_NAME)
87      @Requirement(reqId = Requirement.DOI_SRV_040, reqName = Requirement.DOI_SRV_040_NAME)
88      @Requirement(reqId = Requirement.DOI_MONIT_020, reqName = Requirement.DOI_MONIT_020_NAME)
89      @Requirement(reqId = Requirement.DOI_INTER_070, reqName = Requirement.DOI_INTER_070_NAME)
90      @Requirement(reqId = Requirement.DOI_AUTO_020, reqName = Requirement.DOI_AUTO_020_NAME)
91      @Requirement(reqId = Requirement.DOI_AUTO_030, reqName = Requirement.DOI_AUTO_030_NAME)
92      @Post
93      public String createMetadata(final Representation entity) throws DoiServerException {
94          LOG.traceEntry("Parameter\n\tentity:{}", entity);
95          checkInputs(entity);
96          final String result;
97          try {
98              setStatus(Status.SUCCESS_CREATED);
99              final Resource resource = createDataCiteResourceObject(entity);
100             final String selectedRole = extractSelectedRoleFromRequestIfExists();
101             checkPermission(resource.getIdentifier().getValue(), selectedRole);
102             resource.setPublisher("CNES");
103             result = this.getDoiApp().getClient().createMetadata(resource);
104         } catch (ClientMdsException ex) {
105             throw LOG.throwing(Level.ERROR,
106                     new DoiServerException(getApplication(), API_MDS.DATACITE_PROBLEM, ex.
107                             getMessage(), ex)
108             );
109         } catch (ValidationException ex) {
110             throw LOG.throwing(Level.ERROR,
111                     new DoiServerException(getApplication(), API_MDS.METADATA_VALIDATION,
112                             "invalid XML", ex)
113             );
114         } catch (JAXBException ex) {
115             throw LOG.throwing(Level.ERROR,
116                     new DoiServerException(getApplication(), API_MDS.METADATA_VALIDATION,
117                             "invalid XML", ex)
118             );
119         } catch (SAXException ex) {
120             throw LOG.throwing(Level.ERROR,
121                     new DoiServerException(getApplication(), API_MDS.NETWORK_PROBLEM,
122                             "DataCite schema not available", ex)
123             );
124         }
125         return LOG.traceExit(result);
126     }
127 
128     /**
129      * Checks inputs.
130      *
131      * Checks if <i>obj</i> is {@link #isObjectExist set}
132      *
133      * @param obj object to check
134      * @throws DoiServerException - {@link API_MDS#METADATA_VALIDATION}
135      */
136     @Requirement(reqId = Requirement.DOI_INTER_070, reqName = Requirement.DOI_INTER_070_NAME)
137     private void checkInputs(final Object obj) throws DoiServerException {
138         LOG.traceEntry("Parameter : " + obj);
139         if (isObjectNotExist(obj)) {
140             throw LOG.throwing(Level.ERROR,
141                     new DoiServerException(getApplication(), API_MDS.METADATA_VALIDATION,
142                             "Input is not set")
143             );
144         }
145         LOG.traceExit();
146     }
147 
148     /**
149      * Creates the metadata object from its representation.
150      *
151      * @param entity metadata representation
152      * @return the metadata object
153      * @throws JAXBException - if an error was encountered while creating the
154      * JAXBContex
155      * @throws SAXException - if a SAX error occurs during parsing.
156      * @throws ValidationException - if metadata is not valid against the schema
157      */
158     @Requirement(reqId = Requirement.DOI_INTER_060, reqName = Requirement.DOI_INTER_060_NAME)
159     @Requirement(reqId = Requirement.DOI_INTER_070, reqName = Requirement.DOI_INTER_070_NAME)
160     private Resource createDataCiteResourceObject(final Representation entity)
161             throws JAXBException, SAXException, ValidationException {
162         LOG.traceEntry("Parameter : " + entity);
163         return LOG.traceExit(this.getDoiApp().getClient().parseMetadata(entity));
164     }
165 
166     /**
167      * Describes the POST method.
168      *
169      * This request stores new version of DOI metadata. The request body must
170      * contain a valid XML.
171      *
172      * <ul>
173      * <li>{@link API_MDS#CREATE_METADATA}</li>
174      * <li>{@link API_MDS#METADATA_VALIDATION}</li>
175      * <li>{@link API_MDS#DATACITE_PROBLEM}</li>
176      * <li>{@link API_MDS#NETWORK_PROBLEM}</li>
177      * <li>{@link API_MDS#SECURITY_USER_NO_ROLE}</li>
178      * <li>{@link API_MDS#SECURITY_USER_NOT_IN_SELECTED_ROLE}</li>
179      * <li>{@link API_MDS#SECURITY_USER_PERMISSION}</li>
180      * <li>{@link API_MDS#SECURITY_USER_CONFLICT}</li>
181      * </ul>
182      *
183      * @param info Wadl description for POST method
184      */
185     @Requirement(reqId = Requirement.DOI_DOC_010, reqName = Requirement.DOI_DOC_010_NAME)
186     @Override
187     protected final void describePost(final MethodInfo info) {
188         info.setName(Method.POST);
189         info.setDocumentation("This request stores new version of metadata. "
190                 + "The request body must contain a valid XML.");
191 
192         addRequestDocToMethod(info,
193                 Arrays.asList(
194                         createQueryParamDoc("selectedRole",
195                                 ParameterStyle.HEADER,
196                                 "A user can select one role when he is associated "
197                                 + "to several roles", false, "xs:string"
198                         )
199                 ),
200                 createQueryRepresentationDoc("metadataRepresentation",
201                         MediaType.APPLICATION_XML,
202                         "DataCite metadata",
203                         "default:Resource"
204                 )
205         );
206 
207         addResponseDocToMethod(info, createResponseDoc(API_MDS.CREATE_METADATA.getStatus(),
208                 API_MDS.CREATE_METADATA.getShortMessage(),
209                 "explainRepresentationID")
210         );
211         addResponseDocToMethod(info, createResponseDoc(API_MDS.METADATA_VALIDATION.getStatus(),
212                 API_MDS.METADATA_VALIDATION.getShortMessage(),
213                 "explainRepresentationID")
214         );
215         addResponseDocToMethod(info, createResponseDoc(API_MDS.DATACITE_PROBLEM.getStatus(),
216                 API_MDS.DATACITE_PROBLEM.getShortMessage(),
217                 "explainRepresentationID")
218         );
219         addResponseDocToMethod(info, createResponseDoc(API_MDS.NETWORK_PROBLEM.getStatus(),
220                 API_MDS.NETWORK_PROBLEM.getShortMessage(),
221                 "explainRepresentationID")
222         );
223         super.describePost(info);
224 
225     }
226 
227 }