View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.pi.doi;
20  
21  import java.io.IOException;
22  import java.util.Date;
23  import java.util.HashMap;
24  import java.util.Locale;
25  import java.util.Map;
26  import java.util.Optional;
27  
28  import javax.xml.validation.Schema;
29  
30  import org.jdom2.Document;
31  import org.jdom2.transform.JDOMSource;
32  import org.mycore.backend.jpa.MCREntityManagerProvider;
33  import org.mycore.common.config.MCRConfigurationException;
34  import org.mycore.common.content.transformer.MCRContentTransformer;
35  import org.mycore.common.content.transformer.MCRContentTransformerFactory;
36  import org.mycore.common.xml.MCRXMLHelper;
37  import org.mycore.datamodel.metadata.MCRBase;
38  import org.mycore.datamodel.metadata.MCRMetadataManager;
39  import org.mycore.datamodel.metadata.MCRObjectID;
40  import org.mycore.pi.MCRPIJobService;
41  import org.mycore.pi.MCRPIManager;
42  import org.mycore.pi.backend.MCRPI;
43  import org.mycore.pi.exceptions.MCRPersistentIdentifierException;
44  import org.xml.sax.SAXException;
45  
46  import jakarta.persistence.NoResultException;
47  
48  /**
49   * A doi Base Service which contains common DOI registration code.
50   */
51  public abstract class MCRDOIBaseService extends MCRPIJobService<MCRDigitalObjectIdentifier> {
52  
53      protected static final String CONTEXT_OBJ = "obj";
54  
55      protected static final String CONTEXT_DOI = "doi";
56  
57      private static final String CONFIG_TRANSFORMER = "Transformer";
58  
59      private static final String CONFIG_USER_NAME = "Username";
60  
61      private static final String CONFIG_PASSWORD = "Password";
62  
63      private static final String CONFIG_SCHEMA = "Schema";
64  
65      private static final String TYPE = "doi";
66  
67      private String username;
68  
69      private String password;
70  
71      private Schema schema;
72  
73      private String transformerID;
74  
75      public MCRDOIBaseService() {
76          super(TYPE);
77      }
78  
79      protected void initCommonProperties() {
80          setUsername(requireNotEmptyProperty(CONFIG_USER_NAME));
81          setPassword(requireNotEmptyProperty(CONFIG_PASSWORD));
82          setTransformerID(requireNotEmptyProperty(CONFIG_TRANSFORMER));
83  
84          final MCRContentTransformer transformer = getTransformer();
85  
86          final Map<String, String> properties = getProperties();
87          final String schemaURLString = properties.getOrDefault(CONFIG_SCHEMA, getDefaultSchemaPath());
88          setSchema(resolveSchema(schemaURLString));
89      }
90  
91      public static Schema resolveSchema(final String schemaURLString) {
92          try {
93              return MCRXMLHelper.resolveSchema(schemaURLString, true);
94          } catch (SAXException | IOException e) {
95              throw new MCRConfigurationException("Error while loading " + schemaURLString + " schema!", e);
96          }
97      }
98  
99      protected abstract String getDefaultSchemaPath();
100 
101     @Override
102     protected Optional<String> getJobInformation(Map<String, String> contextParameters) {
103         String pattern = "{0} DOI: {1} for object: {2}";
104         return Optional.of(String.format(Locale.ROOT, pattern, getAction(contextParameters).toString(),
105             contextParameters.get(CONTEXT_DOI), contextParameters.get(CONTEXT_OBJ)));
106     }
107 
108     protected boolean checkJobValid(String mycoreID, PiJobAction action) {
109         final MCRObjectID objectID = MCRObjectID.getInstance(mycoreID);
110         final boolean exists = MCRMetadataManager.exists(objectID);
111 
112         try {
113             MCRPIManager.getInstance().get(getServiceID(), mycoreID, "");
114         } catch (NoResultException r) {
115             return false;
116         }
117 
118         return exists;
119     }
120 
121     @Override
122     public void update(MCRDigitalObjectIdentifier doi, MCRBase obj, String additional)
123         throws MCRPersistentIdentifierException {
124         if (isRegistered(obj.getId(), additional)) {
125             HashMap<String, String> contextParameters = new HashMap<>();
126             contextParameters.put(CONTEXT_DOI, doi.asString());
127             contextParameters.put(CONTEXT_OBJ, obj.getId().toString());
128             this.addUpdateJob(contextParameters);
129         } else if (!hasRegistrationStarted(obj.getId(), additional)
130             && getRegistrationPredicate().test(obj)) {
131             // validate
132             transform(obj, doi.asString());
133             this.updateStartRegistrationDate(obj.getId(), "", new Date());
134             startRegisterJob(obj, doi);
135         }
136     }
137 
138     @Override
139     public MCRPI insertIdentifierToDatabase(MCRBase obj, String additional, MCRDigitalObjectIdentifier identifier) {
140         Date registrationStarted = null;
141         if (getRegistrationPredicate().test(obj)) {
142             registrationStarted = new Date();
143             startRegisterJob(obj, identifier);
144         }
145 
146         MCRPI databaseEntry = new MCRPI(identifier.asString(), getType(), obj.getId().toString(), additional,
147             this.getServiceID(), provideRegisterDate(obj, additional), registrationStarted);
148         MCREntityManagerProvider.getCurrentEntityManager().persist(databaseEntry);
149         return databaseEntry;
150     }
151 
152     protected void startRegisterJob(MCRBase obj, MCRDigitalObjectIdentifier newDOI) {
153         HashMap<String, String> contextParameters = new HashMap<>();
154         contextParameters.put(CONTEXT_DOI, newDOI.asString());
155         contextParameters.put(CONTEXT_OBJ, obj.getId().toString());
156         this.addRegisterJob(contextParameters);
157     }
158 
159     protected MCRContentTransformer getTransformer() {
160         return MCRContentTransformerFactory.getTransformer(transformerID);
161     }
162 
163     protected void validateDocument(String id, Document resultDocument)
164         throws MCRPersistentIdentifierException {
165         try {
166             getSchema().newValidator().validate(new JDOMSource(resultDocument));
167         } catch (SAXException | IOException e) {
168             throw new MCRPersistentIdentifierException(
169                 "Error while validating generated xml for " + id, e);
170         }
171     }
172 
173     @Override
174     protected Date provideRegisterDate(MCRBase obj, String additional) {
175         return null;
176     }
177 
178     protected abstract Document transform(MCRBase obj, String pi)
179         throws MCRPersistentIdentifierException;
180 
181     public String getUsername() {
182         return username;
183     }
184 
185     public void setUsername(String username) {
186         this.username = username;
187     }
188 
189     public String getPassword() {
190         return password;
191     }
192 
193     public void setPassword(String password) {
194         this.password = password;
195     }
196 
197     public Schema getSchema() {
198         return schema;
199     }
200 
201     public void setSchema(Schema schema) {
202         this.schema = schema;
203     }
204 
205     public String getTransformerID() {
206         return transformerID;
207     }
208 
209     public void setTransformerID(String transformerID) {
210         this.transformerID = transformerID;
211     }
212 }