Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: leinfelder $'
7
 *     '$Date: 2013-03-12 16:44:41 -0700 (Tue, 12 Mar 2013) $'
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 */
23
package edu.ucsb.nceas.metacat.dataone;
24

    
25
import java.text.SimpleDateFormat;
26
import java.util.HashMap;
27

    
28
import org.apache.log4j.Logger;
29
import org.dataone.service.exceptions.InvalidRequest;
30
import org.dataone.service.exceptions.NotImplemented;
31
import org.dataone.service.exceptions.ServiceFailure;
32
import org.dataone.service.types.v1.Identifier;
33
import org.dataone.service.types.v1.Node;
34
import org.dataone.service.types.v1.SystemMetadata;
35

    
36
import edu.ucsb.nceas.ezid.EZIDException;
37
import edu.ucsb.nceas.ezid.EZIDService;
38
import edu.ucsb.nceas.ezid.profile.DataCiteProfile;
39
import edu.ucsb.nceas.ezid.profile.DataCiteProfileResourceTypeValues;
40
import edu.ucsb.nceas.ezid.profile.ErcMissingValueCode;
41
import edu.ucsb.nceas.ezid.profile.InternalProfile;
42
import edu.ucsb.nceas.ezid.profile.InternalProfileValues;
43
import edu.ucsb.nceas.metacat.properties.PropertyService;
44
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
45

    
46
/**
47
 * 
48
 * Singleton for interacting with the EZID DOI library.
49
 * Allows DOI minting/initial registration, creating and updating 
50
 * existing DOI registrations.
51
 * 
52
 * @author leinfelder
53
 */
54
public class DOIService {
55

    
56
	private Logger logMetacat = Logger.getLogger(DOIService.class);
57

    
58
	private static DOIService instance = null;
59
	
60
	public static DOIService getInstance() {
61
		if (instance == null) {
62
			instance = new DOIService();
63
		}
64
		return instance;
65
	}
66
	
67
	/**
68
	 * Constructor, private for singleton access
69
	 */
70
	private DOIService() {
71
		
72
	}
73
	
74
	/**
75
	 * submits DOI metadata information about the object to EZID
76
	 * @param sysMeta
77
	 * @return
78
	 * @throws EZIDException 
79
	 * @throws ServiceFailure 
80
	 * @throws NotImplemented 
81
	 */
82
	public boolean registerDOI(SystemMetadata sysMeta) throws EZIDException, NotImplemented, ServiceFailure {
83
		
84
		// for DOIs
85
		String ezidUsername = null;
86
		String ezidPassword = null;
87
		String shoulder = null;
88
		boolean doiEnabled = false;
89
		try {
90
            doiEnabled = new Boolean(PropertyService.getProperty("guid.ezid.enabled")).booleanValue();
91
			shoulder = PropertyService.getProperty("guid.ezid.doishoulder.1");
92
			ezidUsername = PropertyService.getProperty("guid.ezid.username");
93
			ezidPassword = PropertyService.getProperty("guid.ezid.password");
94
		} catch (PropertyNotFoundException e) {
95
			logMetacat.warn("DOI support is not configured at this node.", e);
96
			return false;
97
		}
98
		
99
		// only continue if we have the feature turned on
100
		if (doiEnabled) {
101
			
102
			String identifier = sysMeta.getIdentifier().getValue();
103
			
104
			// only continue if this DOI is in our configured shoulder
105
			if (identifier.startsWith(shoulder)) {
106
				
107
				// enter metadata about this identifier
108
				HashMap<String, String> metadata = null;
109
				
110
				// login to EZID service
111
				String ezidServiceBaseUrl = null;
112
				try {
113
					ezidServiceBaseUrl = PropertyService.getProperty("guid.ezid.baseurl");
114
				} catch (PropertyNotFoundException e) {
115
					logMetacat.warn("Using default EZID baseUrl");
116
				}
117
				EZIDService ezid = new EZIDService(ezidServiceBaseUrl);
118
				ezid.login(ezidUsername, ezidPassword);
119
				
120
				// check for existing metadata
121
				boolean create = false;
122
				try {
123
					metadata = ezid.getMetadata(identifier);
124
				} catch (EZIDException e) {
125
					// expected much of the time
126
					logMetacat.warn("No metadata found for given identifier: " + e.getMessage());
127
				}
128
				if (metadata == null) {
129
					create = true;
130
				}
131
				// confuses the API if we send the original metadata that it gave us, so start from scratch
132
				metadata = new HashMap<String, String>();
133
				
134
				// TODO: set title and creator to better values
135
				Node node = MNodeService.getInstance(null).getCapabilities();
136
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
137
				String year = sdf .format(sysMeta.getDateUploaded());
138
				metadata.put(DataCiteProfile.TITLE.toString(), ErcMissingValueCode.UNKNOWN.toString());
139
				metadata.put(DataCiteProfile.CREATOR.toString(), sysMeta.getRightsHolder().getValue());
140
				metadata.put(DataCiteProfile.PUBLISHER.toString(), node.getName());
141
				metadata.put(DataCiteProfile.PUBLICATION_YEAR.toString(), year);
142
				metadata.put(DataCiteProfile.RESOURCE_TYPE.toString(), DataCiteProfileResourceTypeValues.DATASET.toString() + "/" + sysMeta.getFormatId().getValue());
143
				metadata.put(InternalProfile.TARGET.toString(), node.getBaseURL() + "/v1/object/" + identifier);
144
				metadata.put(InternalProfile.STATUS.toString(), InternalProfileValues.PUBLIC.toString());
145
				metadata.put(InternalProfile.EXPORT.toString(), InternalProfileValues.YES.toString());
146
	
147
				// set using the API
148
				if (create) {
149
					ezid.createIdentifier(identifier, metadata);
150
				} else {
151
					ezid.setMetadata(identifier, metadata);
152
				}
153
				
154
				ezid.logout();
155
			}
156
			
157
		}
158
		
159
		return true;
160
	}
161

    
162
	/**
163
	 * Generate a DOI using the EZID service as configured
164
	 * @return
165
	 * @throws EZIDException 
166
	 * @throws InvalidRequest 
167
	 */
168
	public Identifier generateDOI() throws EZIDException, InvalidRequest {
169

    
170
		Identifier identifier = new Identifier();
171

    
172
		// look up configuration values
173
		String shoulder = null;
174
		String ezidUsername = null;
175
		String ezidPassword = null;
176
		boolean doiEnabled = false;
177
		try {
178
            doiEnabled = new Boolean(PropertyService.getProperty("guid.ezid.enabled")).booleanValue();
179
			shoulder = PropertyService.getProperty("guid.ezid.doishoulder.1");
180
			ezidUsername = PropertyService.getProperty("guid.ezid.username");
181
			ezidPassword = PropertyService.getProperty("guid.ezid.password");
182
		} catch (PropertyNotFoundException e1) {
183
			throw new InvalidRequest("2193", "DOI shoulder is not configured at this node.");
184
		}
185
		
186
		// only continue if we have the feature turned on
187
		if (!doiEnabled) {
188
			throw new InvalidRequest("2193", "DOI scheme is not enabled at this node.");
189
		}
190
		
191
		// add only the minimal metadata required for this DOI
192
		HashMap<String, String> metadata = new HashMap<String, String>();
193
		metadata.put(DataCiteProfile.TITLE.toString(), ErcMissingValueCode.UNKNOWN.toString());
194
		metadata.put(DataCiteProfile.CREATOR.toString(), ErcMissingValueCode.UNKNOWN.toString());
195
		metadata.put(DataCiteProfile.PUBLISHER.toString(), ErcMissingValueCode.UNKNOWN.toString());
196
		metadata.put(DataCiteProfile.PUBLICATION_YEAR.toString(), ErcMissingValueCode.UNKNOWN.toString());
197
		metadata.put(InternalProfile.STATUS.toString(), InternalProfileValues.RESERVED.toString());
198
		metadata.put(InternalProfile.EXPORT.toString(), InternalProfileValues.NO.toString());
199

    
200
		// call the EZID service
201
		String ezidServiceBaseUrl = null;
202
		try {
203
			ezidServiceBaseUrl = PropertyService.getProperty("guid.ezid.baseurl");
204
		} catch (PropertyNotFoundException e) {
205
			logMetacat.warn("Using default EZID baseUrl");
206
		}
207
		EZIDService ezid = new EZIDService(ezidServiceBaseUrl);
208
		ezid.login(ezidUsername, ezidPassword);
209
		String doi = ezid.mintIdentifier(shoulder, metadata);
210
		identifier.setValue(doi);
211
		ezid.logout();
212
		
213
		return identifier;
214
	}
215

    
216
	
217
}
(3-3/6)