- Timestamp:
- 2014-02-27T10:35:07+13:00 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/OAIXML.java
r27671 r28846 50 50 public class OAIXML { 51 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 52 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.GSXML.class.getName()); 53 54 // the leading keyword of oai protocol 55 public static final String VERB = "verb"; 56 57 // six valid oai verbs 58 public static final String GET_RECORD = "GetRecord"; 59 public static final String LIST_RECORDS = "ListRecords"; 60 public static final String LIST_IDENTIFIERS = "ListIdentifiers"; 61 public static final String LIST_SETS = "ListSets"; 62 public static final String LIST_METADATA_FORMATS = "ListMetadataFormats"; 63 public static final String IDENTIFY = "Identify"; 64 65 // other valid oai parameters 66 public static final String OAI_METADATAFORMAT = "OAIMetadataFormat"; 67 public static final String METADATA_NAMESPACE = "metadataNamespace"; 68 public static final String OAI_DC = "oai_dc"; 69 public static final String DC = "dc"; 70 public static final String METADATA_PREFIX = "metadataPrefix"; 71 public static final String FROM = "from"; 72 public static final String UNTIL = "until"; 73 public static final String SET = "set"; 74 public static final String RESUMPTION_TOKEN = "resumptionToken"; 75 public static final String RESUMPTION_TOKEN_EXPIRATION = "resumptionTokenExpiration"; 76 public static final String IDENTIFIER = "identifier"; 77 78 public static final String USE_STYLESHEET = "useOAIStylesheet"; 79 public static final String STYLESHEET = "OAIStylesheet"; 80 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 81 // words used to compose oai responses and read in OAIConfig.xml 82 public static final String ADMIN_EMAIL = "adminEmail"; 83 public static final String BAD_ARGUMENT = "badArgument"; 84 public static final String BAD_RESUMPTION_TOKEN = "badResumptionToken"; 85 public static final String BAD_VERB = "badVerb"; 86 public static final String BASE_URL = "baseURL"; 87 public static final String CANNOT_DISSEMINATE_FORMAT = "cannotDisseminateFormat"; 88 public static final String CODE = "code"; 89 public static final String COLLECTION = "collection"; 90 public static final String COLLECTION_LIST = "collectionList"; 91 public static final String COMPLETE_LIST_SIZE = "completeListSize"; 92 public static final String COMPRESSION = "compression"; 93 public static final String CURSOR = "cursor"; 94 public static final String DATESTAMP = "datestamp"; 95 public static final String DELETED_RECORD = "deletedRecord"; 96 public static final String DESCRIPTION = "description"; 97 public static final String EARLIEST_DATESTAMP = "earliestDatestamp"; 98 public static final String ERROR = "error"; 99 public static final String EXPIRATION_DATE = "expirationDate"; 100 public static final String GRANULARITY = "granularity"; 101 public static final String GS3OAI = "GS3OAI"; 102 public static final String GS_OAI_RESOURCE_URL = "gs.OAIResourceURL"; 103 public static final String HAS_OAI = "hasOAI"; 104 public static final String HEADER = "header"; 105 public static final String ILLEGAL_OAI_VERB = "Illegal OAI verb"; 106 public static final String INDEX_STEM = "indexStem"; 107 107 public static final String INFO_METADATA = "Metadata"; // this has capital M 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 108 public static final String LASTMODIFIED = "lastmodified"; 109 public static final String MAPPING = "mapping"; 110 public static final String MAPPING_LIST = "mappingList"; 111 public static final String MESSAGE = "message"; 112 public static final String METADATA = "metadata"; 113 public static final String METADATA_FORMAT = "metadataFormat"; 114 public static final String NAME = "name"; 115 public static final String NO_RECORDS_MATCH = "noRecordsMatch"; 116 public static final String OAI = "OAI"; 117 public static final String OAI_DASH_PMH = "OAI-PMH"; 118 public static final String OAI_LASTMODIFIED = "oailastmodified"; 119 public static final String OAIPMH = "OAIPMH"; 120 public static final String OAI_RESUMPTION_TOKENS = "OAIResumptionTokens"; 121 public static final String OAI_INFO = "oaiInfo"; 122 public static final String OAI_SERVICE = "oaiService"; 123 public static final String OAI_SET_LIST = "oaiSetList"; 124 public static final String OAI_SERVICE_UNAVAILABLE = "OAI service unavailable"; 125 public static final String OID = "OID"; 126 public static final String PARAM = "param"; 127 public static final String PARAM_LIST = "paramList"; 128 public static final String PROTOCOL_VERSION = "protocolVersion"; 129 public static final String RECORD = "record"; 130 public static final String REQUEST = "request"; 131 public static final String REPOSITORY_NAME = "repositoryName"; 132 public static final String REPOSITORY_ID = "repositoryId"; 133 public static final String RESPONSE = "response"; 134 public static final String RESPONSE_DATE = "responseDate"; 135 public static final String RESUME_AFTER = "resumeAfter"; 136 public static final String SCHEMA = "schema"; 137 public static final String SERVICE = "service"; 138 public static final String SERVICE_UNAVAILABLE = "service unavailable"; 139 public static final String SET_SPEC = "setSpec"; 140 public static final String SET_NAME = "setName"; 141 public static final String SET_DESCRIPTION = "setDescription"; 142 public static final String SITE = "site"; 143 public static final String TO = "to"; 144 public static final String TYPE = "type"; 145 public static final String VALUE = "value"; 146 147 //Two error and exception conditions for the verb 'ListMetadataFormats' 148 public static final String ID_DOES_NOT_EXIST = "idDoesNotExist"; 149 public static final String NO_METADATA_FORMATS = "noMetadataFormats"; 150 151 // The node id in the collection database, which contains all the OIDs in the database 152 public static final String BROWSELIST = "browselist"; 153 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 // /** key=special character; value=escaped sequence */192 // public static HashMap encode_map = new HashMap();193 // /** key=escaped sequence; value=special character */194 // public static HashMap decode_map = new HashMap();195 196 197 198 199 200 201 154 //system-dependent file separator, maybe '/' or '\' 155 public static final String FILE_SEPARATOR = File.separator; 156 public static final String OAI_VERSION1 = "1.0"; 157 public static final String OAI_VERSION2 = "2.0"; 158 /*************************above are final values****************************/ 159 160 public static Element resumption_token_elem = null; 161 //used when saving the token file 162 public static File resumption_token_file = null; 163 //public static ArrayList token_list = new ArrayList(); 164 165 //initialized in getOAIConfigXML() 166 public static Element oai_config_elem = null; 167 168 //stores the date format "yyyy-MM-ddTHH:mm:ssZ" 169 public static String granularity = ""; 170 171 // http://www.openarchives.org/OAI/openarchivesprotocol.html#DatestampsRequests 172 // specifies that all repositories must support YYYY-MM-DD (yyyy-MM-dd in Java) 173 // this would be in addition to the other (optional) granularity of above that 174 // a repository may additionally choose to support. 175 public static final String default_granularity = "yyyy-MM-dd"; 176 177 //this value is overriden in getOAIConfigXML() 178 public static long token_expiration = 7200; 179 180 /** which version of oai that this oaiserver supports; default is 2.0 181 * initialized in getOAIConfigXML() 182 */ 183 public static String oai_version = "2.0"; 184 public static String baseURL = ""; 185 186 /**response owner document */ 187 public static Document response_doc = new XMLConverter().newDOM(); 188 189 public static String[] special_char = {"/", "?", "#", "=", "&", ":", ";", " ", "%", "+"}; 190 public static String[] escape_sequence = {"%2F", "%3F", "%23", "%3D", "%26", "%3A", "%3B", "%20", "%25", "%2B"}; 191 // /** key=special character; value=escaped sequence */ 192 // public static HashMap encode_map = new HashMap(); 193 // /** key=escaped sequence; value=special character */ 194 // public static HashMap decode_map = new HashMap(); 195 196 public static void init() { 197 resumption_token_elem = getOAIResumptionTokenXML(); 198 } 199 public static String getOAIVersion() { 200 return oai_version; 201 } 202 202 203 204 205 203 public static String getBaseURL() { 204 return baseURL; 205 } 206 206 207 public static Element createElement(String tag_name) { 208 return response_doc.createElement(tag_name); 209 } 210 /**Compose a response element used when OAIPMH service sending responses thru 211 * ServiceCluster and MessageRouter, as they automatically wrap a message element 212 * on this response element 213 */ 214 public static Element getResponse(Element core_msg) { 215 Element res = createElement(RESPONSE); 216 res.appendChild(response_doc.importNode(core_msg, true)); 217 return res; 218 } 219 /** Read in OAIResumptionToken.xml (residing web/WEB-INF/classes/) */ 220 public static Element getOAIResumptionTokenXML() { 221 222 // The system environment variable $GSDL3HOME(ends ../web) does not contain the file separator 223 resumption_token_file = new File(GlobalProperties.getGSDL3Home() + FILE_SEPARATOR + 224 "WEB-INF" + FILE_SEPARATOR + "classes" +FILE_SEPARATOR + "OAIResumptionToken.xml"); 225 if (resumption_token_file.exists()) { 226 Document token_doc = parseXMLFile(resumption_token_file); 227 if (token_doc != null) { 228 resumption_token_elem = token_doc.getDocumentElement(); 229 } else { 230 logger.error("Fail to parse resumption token file OAIReceptionToken.xml."); 231 return null; 232 } 233 //remove all expired tokens 234 clearExpiredTokens(); 235 return resumption_token_elem; 236 } 237 //if resumption_token_file does not exist 238 logger.info("resumption token file: "+ resumption_token_file.getPath()+" not found! create an empty one."); 239 resumption_token_elem = createElement(OAI_RESUMPTION_TOKENS); 207 public static Element createElement(String tag_name) { 208 return response_doc.createElement(tag_name); 209 } 210 /**Compose a response element used when OAIPMH service sending responses thru 211 * ServiceCluster and MessageRouter, as they automatically wrap a message element 212 * on this response element 213 */ 214 public static Element getResponse(Element core_msg) { 215 Element res = createElement(RESPONSE); 216 res.appendChild(response_doc.importNode(core_msg, true)); 217 return res; 218 } 219 /** Read in OAIResumptionToken.xml (residing web/WEB-INF/classes/) */ 220 public static Element getOAIResumptionTokenXML() { 221 222 // The system environment variable $GSDL3HOME(ends ../web) does not contain the file separator 223 resumption_token_file = new File(GlobalProperties.getGSDL3Home() + FILE_SEPARATOR + 224 "WEB-INF" + FILE_SEPARATOR + "classes" +FILE_SEPARATOR + "OAIResumptionToken.xml"); 225 if (resumption_token_file.exists()) { 226 Document token_doc = parseXMLFile(resumption_token_file); 227 if (token_doc != null) { 228 resumption_token_elem = token_doc.getDocumentElement(); 229 } else { 230 logger.error("Fail to parse resumption token file OAIReceptionToken.xml."); 231 return null; 232 } 233 //remove all expired tokens 234 clearExpiredTokens(); 235 return resumption_token_elem; 236 } 237 //if resumption_token_file does not exist 238 logger.info("resumption token file: "+ resumption_token_file.getPath()+" not found! create an empty one."); 239 resumption_token_elem = createElement(OAI_RESUMPTION_TOKENS); 240 saveOAIResumptionTokenXML(resumption_token_elem); 241 return resumption_token_elem; 242 } 243 public static void saveOAIResumptionTokenXML(Element token_elem) { 244 if(writeXMLFile(resumption_token_file, token_elem.getOwnerDocument()) == false) { 245 logger.error("Fail to save the resumption token file"); 246 } 247 } 248 public static void clearExpiredTokens() { 249 boolean token_deleted = false; 250 NodeList tokens = GSXML.getChildrenByTagName(resumption_token_elem, RESUMPTION_TOKEN); 251 for (int i=0; i<tokens.getLength(); i++) { 252 Element token_elem = (Element)tokens.item(i); 253 String expire_str = token_elem.getAttribute(EXPIRATION_DATE); 254 long datestamp = getTime(expire_str); // expire_str is in milliseconds 255 if(datestamp < System.currentTimeMillis()) { 256 resumption_token_elem.removeChild(token_elem); 257 token_elem = null; 258 token_deleted = true; 259 } 260 } 261 262 if(token_deleted) { 240 263 saveOAIResumptionTokenXML(resumption_token_elem); 241 return resumption_token_elem; 242 } 243 public static void saveOAIResumptionTokenXML(Element token_elem) { 244 if(writeXMLFile(resumption_token_file, token_elem.getOwnerDocument()) == false) { 245 logger.error("Fail to save the resumption token file"); 246 } 247 } 248 public static void clearExpiredTokens() { 249 boolean token_deleted = false; 250 NodeList tokens = GSXML.getChildrenByTagName(resumption_token_elem, RESUMPTION_TOKEN); 251 for (int i=0; i<tokens.getLength(); i++) { 252 Element token_elem = (Element)tokens.item(i); 253 String expire_str = token_elem.getAttribute(EXPIRATION_DATE); 254 long datestamp = getTime(expire_str); // expire_str is in milliseconds 255 if(datestamp < System.currentTimeMillis()) { 256 resumption_token_elem.removeChild(token_elem); 257 token_elem = null; 258 token_deleted = true; 259 } 260 } 261 262 if(token_deleted) { 263 saveOAIResumptionTokenXML(resumption_token_elem); 264 } 265 } 266 public static boolean containsToken(String token) { 267 NodeList tokens = GSXML.getChildrenByTagName(resumption_token_elem, OAIXML.RESUMPTION_TOKEN); 268 for (int i=0; i<tokens.getLength(); i++) { 269 if(token.equals(GSXML.getNodeText((Element)tokens.item(i)).trim() )) 270 return true; 271 } 272 return false; 273 } 274 public static void addToken(Element token) { 275 Document doc = resumption_token_elem.getOwnerDocument(); 276 resumption_token_elem.appendChild(duplicateElement(doc, token, true)); 277 saveOAIResumptionTokenXML(resumption_token_elem); 278 } 279 public static void addToken(String token) { 280 Element te = resumption_token_elem.getOwnerDocument().createElement(OAIXML.RESUMPTION_TOKEN); 281 //add expiration att 282 resumption_token_elem.appendChild(te); 283 saveOAIResumptionTokenXML(resumption_token_elem); 284 } 285 public static boolean removeToken(String token) { 286 NodeList tokens = GSXML.getChildrenByTagName(resumption_token_elem, OAIXML.RESUMPTION_TOKEN); 287 int num_tokens = tokens.getLength(); 288 for (int i=0; i<num_tokens; i++) { 289 Element e = (Element)(tokens.item(i)); 290 if(token.equals(GSXML.getNodeText(e))) { 291 resumption_token_elem.removeChild(e); 292 saveOAIResumptionTokenXML(resumption_token_elem); 293 return true; 294 } 295 } 296 return false; 297 } 298 /** Read in OAIConfig.xml (residing web/WEB-INF/classes/) and use it to configure the receptionist etc. 299 * the oai_version and baseURL variables are also set in here. 300 * The init() method is also called in here. */ 301 public static Element getOAIConfigXML() { 302 init(); 264 } 265 } 266 public static boolean containsToken(String token) { 267 NodeList tokens = GSXML.getChildrenByTagName(resumption_token_elem, OAIXML.RESUMPTION_TOKEN); 268 for (int i=0; i<tokens.getLength(); i++) { 269 if(token.equals(GSXML.getNodeText((Element)tokens.item(i)).trim() )) 270 return true; 271 } 272 return false; 273 } 274 public static void addToken(Element token) { 275 Document doc = resumption_token_elem.getOwnerDocument(); 276 resumption_token_elem.appendChild(duplicateElement(doc, token, true)); 277 saveOAIResumptionTokenXML(resumption_token_elem); 278 } 279 public static void addToken(String token) { 280 Element te = resumption_token_elem.getOwnerDocument().createElement(OAIXML.RESUMPTION_TOKEN); 281 //add expiration att 282 resumption_token_elem.appendChild(te); 283 saveOAIResumptionTokenXML(resumption_token_elem); 284 } 285 public static boolean removeToken(String token) { 286 NodeList tokens = GSXML.getChildrenByTagName(resumption_token_elem, OAIXML.RESUMPTION_TOKEN); 287 int num_tokens = tokens.getLength(); 288 for (int i=0; i<num_tokens; i++) { 289 Element e = (Element)(tokens.item(i)); 290 if(token.equals(GSXML.getNodeText(e))) { 291 resumption_token_elem.removeChild(e); 292 saveOAIResumptionTokenXML(resumption_token_elem); 293 return true; 294 } 295 } 296 return false; 297 } 298 /** Read in OAIConfig.xml (residing web/WEB-INF/classes/) and use it to configure the receptionist etc. 299 * the oai_version and baseURL variables are also set in here. 300 * The init() method is also called in here. */ 301 public static Element getOAIConfigXML() { 302 init(); 303 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 304 // The system environment variable $GSDL3HOME(ends ../web) does not contain the file separator 305 File oai_config_file = new File(GlobalProperties.getGSDL3Home() + FILE_SEPARATOR + 306 "WEB-INF" + FILE_SEPARATOR + "classes" +FILE_SEPARATOR + "OAIConfig.xml"); 307 if (!oai_config_file.exists()) { 308 logger.error(" oai config file: "+oai_config_file.getPath()+" not found!"); 309 return null; 310 } 311 Document oai_config_doc = parseXMLFile(oai_config_file); 312 if (oai_config_doc != null) { 313 oai_config_elem = oai_config_doc.getDocumentElement(); 314 } else { 315 logger.error("Fail to parse oai config file OAIConfig.xml."); 316 return null; 317 } 318 319 //initialize oai_version 320 Element protocol_version = (Element)GSXML.getChildByTagName(oai_config_elem, PROTOCOL_VERSION); 321 oai_version = GSXML.getNodeText(protocol_version).trim(); 322 323 // initialize baseURL 324 Element base_url_elem = (Element)GSXML.getChildByTagName(oai_config_elem, BASE_URL); 325 baseURL = GSXML.getNodeText(base_url_elem); 326 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 327 //initialize token_expiration 328 Element expiration = (Element)GSXML.getChildByTagName(oai_config_elem, RESUMPTION_TOKEN_EXPIRATION); 329 String expire_str = GSXML.getNodeText(expiration).trim(); 330 if (expiration != null && !expire_str.equals("")) { 331 token_expiration = Long.parseLong(expire_str); 332 } 333 334 // read granularity from the config file 335 Element granu_elem = (Element)GSXML.getChildByTagName(oai_config_elem, GRANULARITY); 336 //initialize the granu_str which might be used by other methods (eg, getDate()) 337 granularity = GSXML.getNodeText(granu_elem).trim(); 338 339 //change "yyyy-MM-ddTHH:mm:ssZ" to "yyyy-MM-dd'T'HH:mm:ss'Z'" 340 granularity = granularity.replaceAll("T", "'T'"); 341 granularity = granularity.replaceAll("Z", "'Z'"); 342 granularity = granularity.replaceAll("YYYY", "yyyy").replaceAll("DD", "dd").replaceAll("hh", "HH"); 343 return oai_config_elem; 344 } 345 345 346 346 public static String[] getMetadataMapping(Element metadata_format) { … … 363 363 } 364 364 365 public static String[] getGlobalMetadataMapping(String prefix) { 366 Element list_meta_formats = (Element)GSXML.getChildByTagName(oai_config_elem, LIST_METADATA_FORMATS); 367 if(list_meta_formats == null) { 368 return null; 369 } 370 Element metadata_format = GSXML.getNamedElement(list_meta_formats, METADATA_FORMAT, METADATA_PREFIX, prefix); 371 if(metadata_format == null) { 372 return null; 373 } 374 return getMetadataMapping(metadata_format); 375 } 376 377 378 public static long getTokenExpiration() { 379 return token_expiration*1000; // in milliseconds 380 } 381 382 /** TODO: returns a basic response for appropriate oai version 383 * 384 */ 385 public static Element createBasicResponse(String verb, String[] pairs) { 386 387 Element response = createResponseHeader(verb); 388 389 //set the responseDate and request elements accordingly 390 Element request_elem = (Element)GSXML.getChildByTagName(response, REQUEST); 391 if (verb.equals("")) { 392 request_elem.setAttribute(VERB, verb); 393 } 394 int num_pairs = (pairs==null)? 0 : pairs.length; 395 for (int i=num_pairs - 1; i>=0; i--) { 396 int index = pairs[i].indexOf("="); 397 if (index != -1) { 398 String[] strs = pairs[i].split("="); 399 if(strs != null && strs.length == 2) { 400 request_elem.setAttribute(strs[0], oaiDecode(strs[1])); 401 } 402 } 403 }//end of for() 404 405 GSXML.setNodeText(request_elem, baseURL); 406 407 Node resp_date = GSXML.getChildByTagName(response, RESPONSE_DATE); 408 if (resp_date != null) { 409 GSXML.setNodeText((Element)resp_date, getCurrentUTCTime()); 410 } 411 412 return response; 413 } 414 /** @param error_code the value of the code attribute 415 * @param error_text the node text of the error element 416 * @return an oai error element 417 * Used by receptionist 418 */ 419 public static Element createErrorElement(String error_code, String error_text) { 420 Element error = createElement(ERROR); 421 error.setAttribute(CODE, error_code); 422 GSXML.setNodeText(error, error_text); 423 return error; 424 } 425 426 /** convert the escaped sequences (eg, '%3A') of those special characters back to their 427 * original form (eg, ':'). 428 */ 429 public static String oaiDecode(String escaped_str) { 430 logger.info("oaiDecode() " +escaped_str); 431 for (int i=0; i<special_char.length; i++) { 432 if (escaped_str.indexOf(escape_sequence[i]) != -1) { 433 escaped_str = escaped_str.replaceAll(escape_sequence[i], special_char[i]); 434 } 435 } 436 //escaped_str = escaped_str.replaceAll("%3A", ":"); 437 return escaped_str; 438 } 439 /** convert those special characters (eg, ':') to their 440 * escaped sequences (eg, '%3A'). 441 */ 442 public static String oaiEncode(String original_str) { 443 logger.info("oaiEncode() " + original_str); 444 for (int i=0; i<special_char.length; i++) { 445 if (original_str.indexOf(special_char[i]) != -1) { 446 original_str = original_str.replaceAll(special_char[i], escape_sequence[i]); 447 } 448 } 449 //original_str = original_str.replaceAll(":", "%3A"); 450 return original_str; 451 } 452 /** convert YYYY-MM_DDThh:mm:ssZ to yyyy-MM-ddTHH:mm:ssZ 453 */ 454 public static String convertToJava(String oai_format) { 455 oai_format = oai_format.replaceAll("YYYY", "yyyy").replaceAll("DD", "dd").replaceAll("hh", "HH"); 456 return oai_format; 457 } 458 /** convert yyyy-MM-ddTHH:mm:ssZ to YYYY-MM_DDThh:mm:ssZ 459 */ 460 public static String convertToOAI(String java_format) { 461 java_format = java_format.replaceAll("yyyy", "YYYY").replaceAll("dd", "DD").replaceAll("HH", "hh"); 462 return java_format; 463 } 464 public static String getCurrentUTCTime() { 465 Date current_utc = new Date(System.currentTimeMillis()); 466 //granularity is in the form: yyyy-MM-dd'T'HH:mm:ss'Z ' 467 DateFormat formatter = new SimpleDateFormat(granularity); 468 return formatter.format(current_utc); 469 } 470 /** get a Date object from a Date format pattern string 471 * 472 * @param pattern - in the form: 2007-06-14T16:48:25Z, for example. 473 * @return a Date object - null if the pattern is not in the specified form 474 */ 475 476 public static Date getDate(String pattern) { 477 if (pattern == null || pattern.equals("")) { 478 return null; 479 } 480 Date date = null; 481 // String str = pattern.replaceAll("T", " "); 482 // str = str.replaceAll("Z", ""); 483 SimpleDateFormat sdf = null; 484 try { 485 sdf = new SimpleDateFormat(granularity); 486 date = sdf.parse(pattern); 487 } catch(Exception e) { 488 if(!default_granularity.equals(granularity)) { // try validating against default granularity 489 try { 490 date = null; 491 sdf = null; 492 sdf = new SimpleDateFormat(default_granularity); 493 date = sdf.parse(pattern); 494 } catch(Exception ex) { 495 logger.error("invalid date format: " + pattern); 496 return null; 497 } 498 } else { 499 logger.error("invalid date format: " + pattern); 500 return null; 501 } 502 } 503 return date; 504 } 505 /** get the million second value from a string representing time in a pattern 506 * (eg, 2007-06-14T16:48:25Z) 507 */ 508 public static long getTime(String pattern) { 509 if (pattern == null || pattern.equals("")) { 510 return -1; 511 } 512 Date date = null; 513 SimpleDateFormat sdf = null; 514 try { 515 //granularity is a global variable in the form: yyyy-MM-ddTHH:mm:ssZ 516 sdf = new SimpleDateFormat(granularity); 517 date = sdf.parse(pattern); 518 } catch(Exception e) { 519 if(!default_granularity.equals(granularity)) { // try validating against default granularity 520 try { 521 date = null; 522 sdf = null; 523 sdf = new SimpleDateFormat(default_granularity); 524 date = sdf.parse(pattern); 525 } catch(Exception ex) { 526 logger.error("invalid date format: " + pattern); 527 return -1; 528 } 529 } else { 530 logger.error("invalid date format: " + pattern); 531 return -1; 532 } 533 } 534 return date.getTime(); 535 } 536 /** get the string representation of a time from a long value(long type) 537 */ 538 public static String getTime(long milliseconds) { 539 Date date = new Date(milliseconds); 540 SimpleDateFormat sdf = new SimpleDateFormat(granularity); 541 return sdf.format(date); 542 } 543 public static Element createResponseHeader(String verb) { 544 String tag_name = (oai_version.equals(OAI_VERSION2))? OAI_DASH_PMH : verb; 545 Element oai = response_doc.createElement(tag_name); 546 Element resp_date = response_doc.createElement(RESPONSE_DATE); 547 Element req = response_doc.createElement(REQUEST); 548 oai.appendChild(resp_date); 549 oai.appendChild(req); 550 551 if(oai_version.equals(OAI_VERSION2)) { 552 oai.setAttribute("xmlns", "http://www.openarchives.org/OAI/2.0/"); 553 oai.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 554 oai.setAttribute("xsi:schemaLocation", "http://www.openarchives.org/OAI/2.0/ \n http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"); 365 public static String[] getGlobalMetadataMapping(String prefix) { 366 Element list_meta_formats = (Element)GSXML.getChildByTagName(oai_config_elem, LIST_METADATA_FORMATS); 367 if(list_meta_formats == null) { 368 return null; 369 } 370 Element metadata_format = GSXML.getNamedElement(list_meta_formats, METADATA_FORMAT, METADATA_PREFIX, prefix); 371 if(metadata_format == null) { 372 return null; 373 } 374 return getMetadataMapping(metadata_format); 375 } 376 377 378 public static long getTokenExpiration() { 379 return token_expiration*1000; // in milliseconds 380 } 381 382 /** TODO: returns a basic response for appropriate oai version 383 * 384 */ 385 public static Element createBasicResponse(String verb, String[] pairs) { 386 387 Element response = createResponseHeader(verb); 388 389 //set the responseDate and request elements accordingly 390 Element request_elem = (Element)GSXML.getChildByTagName(response, REQUEST); 391 if (verb.equals("")) { 392 request_elem.setAttribute(VERB, verb); 393 } 394 int num_pairs = (pairs==null)? 0 : pairs.length; 395 for (int i=num_pairs - 1; i>=0; i--) { 396 int index = pairs[i].indexOf("="); 397 if (index != -1) { 398 String[] strs = pairs[i].split("="); 399 if(strs != null && strs.length == 2) { 400 request_elem.setAttribute(strs[0], oaiDecode(strs[1])); 401 } 402 } 403 }//end of for() 404 405 GSXML.setNodeText(request_elem, baseURL); 406 407 Node resp_date = GSXML.getChildByTagName(response, RESPONSE_DATE); 408 if (resp_date != null) { 409 GSXML.setNodeText((Element)resp_date, getCurrentUTCTime()); 410 } 411 412 return response; 413 } 414 /** @param error_code the value of the code attribute 415 * @param error_text the node text of the error element 416 * @return an oai error element 417 * Used by receptionist 418 */ 419 public static Element createErrorElement(String error_code, String error_text) { 420 Element error = createElement(ERROR); 421 error.setAttribute(CODE, error_code); 422 GSXML.setNodeText(error, error_text); 423 return error; 424 } 425 426 /** convert the escaped sequences (eg, '%3A') of those special characters back to their 427 * original form (eg, ':'). 428 */ 429 public static String oaiDecode(String escaped_str) { 430 logger.info("oaiDecode() " +escaped_str); 431 for (int i=0; i<special_char.length; i++) { 432 if (escaped_str.indexOf(escape_sequence[i]) != -1) { 433 escaped_str = escaped_str.replaceAll(escape_sequence[i], special_char[i]); 434 } 435 } 436 //escaped_str = escaped_str.replaceAll("%3A", ":"); 437 return escaped_str; 438 } 439 /** convert those special characters (eg, ':') to their 440 * escaped sequences (eg, '%3A'). 441 */ 442 public static String oaiEncode(String original_str) { 443 logger.info("oaiEncode() " + original_str); 444 for (int i=0; i<special_char.length; i++) { 445 if (original_str.indexOf(special_char[i]) != -1) { 446 original_str = original_str.replaceAll(special_char[i], escape_sequence[i]); 447 } 448 } 449 //original_str = original_str.replaceAll(":", "%3A"); 450 return original_str; 451 } 452 /** convert YYYY-MM_DDThh:mm:ssZ to yyyy-MM-ddTHH:mm:ssZ 453 */ 454 public static String convertToJava(String oai_format) { 455 oai_format = oai_format.replaceAll("YYYY", "yyyy").replaceAll("DD", "dd").replaceAll("hh", "HH"); 456 return oai_format; 457 } 458 /** convert yyyy-MM-ddTHH:mm:ssZ to YYYY-MM_DDThh:mm:ssZ 459 */ 460 public static String convertToOAI(String java_format) { 461 java_format = java_format.replaceAll("yyyy", "YYYY").replaceAll("dd", "DD").replaceAll("HH", "hh"); 462 return java_format; 463 } 464 public static String getCurrentUTCTime() { 465 Date current_utc = new Date(System.currentTimeMillis()); 466 //granularity is in the form: yyyy-MM-dd'T'HH:mm:ss'Z ' 467 DateFormat formatter = new SimpleDateFormat(granularity); 468 return formatter.format(current_utc); 469 } 470 /** get a Date object from a Date format pattern string 471 * 472 * @param pattern - in the form: 2007-06-14T16:48:25Z, for example. 473 * @return a Date object - null if the pattern is not in the specified form 474 */ 475 476 public static Date getDate(String pattern) { 477 if (pattern == null || pattern.equals("")) { 478 return null; 479 } 480 Date date = null; 481 // String str = pattern.replaceAll("T", " "); 482 // str = str.replaceAll("Z", ""); 483 SimpleDateFormat sdf = null; 484 try { 485 sdf = new SimpleDateFormat(granularity); 486 date = sdf.parse(pattern); 487 } catch(Exception e) { 488 if(!default_granularity.equals(granularity)) { // try validating against default granularity 489 try { 490 date = null; 491 sdf = null; 492 sdf = new SimpleDateFormat(default_granularity); 493 date = sdf.parse(pattern); 494 } catch(Exception ex) { 495 logger.error("invalid date format: " + pattern); 496 return null; 497 } 555 498 } else { 556 oai.setAttribute("xmlns", "http://www.openarchives.com/OAI/1.1/OAI_" + verb); 557 oai.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 558 oai.setAttribute("xsi:schemaLocation", "http://www.openarchives.org/OAI/1.1/OAI_" + verb + "\n http://www.openarchives.org/OAI/1.1/OAI_" + verb + ".xsd"); 559 } 560 return oai; 561 } 562 public static Element getMetadataPrefixElement(String tag_name, String version) { 563 //examples of tag_name: dc, oai_dc:dc, etc. 564 Element oai = response_doc.createElement(tag_name); 565 if (version.equals(OAI_VERSION2)) { 566 oai.setAttribute("xmlns:oai_dc", "http://www.openarchives.org/OAI/2.0/oai_dc/"); 567 oai.setAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/"); 568 oai.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 569 oai.setAttribute("xsi:schemaLocation", "http://www.openarchives.org/OAI/2.0/oai_dc/ \n http://www.openarchives.org/OAI/2.0/oai_dc.xsd"); 499 logger.error("invalid date format: " + pattern); 500 return null; 501 } 502 } 503 return date; 504 } 505 /** get the million second value from a string representing time in a pattern 506 * (eg, 2007-06-14T16:48:25Z) 507 */ 508 public static long getTime(String pattern) { 509 if (pattern == null || pattern.equals("")) { 510 return -1; 511 } 512 Date date = null; 513 SimpleDateFormat sdf = null; 514 try { 515 //granularity is a global variable in the form: yyyy-MM-ddTHH:mm:ssZ 516 sdf = new SimpleDateFormat(granularity); 517 date = sdf.parse(pattern); 518 } catch(Exception e) { 519 if(!default_granularity.equals(granularity)) { // try validating against default granularity 520 try { 521 date = null; 522 sdf = null; 523 sdf = new SimpleDateFormat(default_granularity); 524 date = sdf.parse(pattern); 525 } catch(Exception ex) { 526 logger.error("invalid date format: " + pattern); 527 return -1; 528 } 570 529 } else { 571 oai.setAttribute("xmlns", "ttp://www.openarchives.com/OAI/1.1/"); 572 oai.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 573 oai.setAttribute("xsi:schemaLocation", "http://www.openarchives.org/OAI/1.1/" + tag_name + ".xsd"); 574 } 575 576 return oai; 577 } 578 public static HashMap<String, Node> getChildrenMapByTagName(Node n, String tag_name) { 530 logger.error("invalid date format: " + pattern); 531 return -1; 532 } 533 } 534 return date.getTime(); 535 } 536 /** get the string representation of a time from a long value(long type) 537 */ 538 public static String getTime(long milliseconds) { 539 Date date = new Date(milliseconds); 540 SimpleDateFormat sdf = new SimpleDateFormat(granularity); 541 return sdf.format(date); 542 } 543 public static Element createResponseHeader(String verb) { 544 String tag_name = (oai_version.equals(OAI_VERSION2))? OAI_DASH_PMH : verb; 545 Element oai = response_doc.createElement(tag_name); 546 Element resp_date = response_doc.createElement(RESPONSE_DATE); 547 Element req = response_doc.createElement(REQUEST); 548 oai.appendChild(resp_date); 549 oai.appendChild(req); 550 551 if(oai_version.equals(OAI_VERSION2)) { 552 oai.setAttribute("xmlns", "http://www.openarchives.org/OAI/2.0/"); 553 oai.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 554 oai.setAttribute("xsi:schemaLocation", "http://www.openarchives.org/OAI/2.0/ \n http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"); 555 } else { 556 oai.setAttribute("xmlns", "http://www.openarchives.com/OAI/1.1/OAI_" + verb); 557 oai.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 558 oai.setAttribute("xsi:schemaLocation", "http://www.openarchives.org/OAI/1.1/OAI_" + verb + "\n http://www.openarchives.org/OAI/1.1/OAI_" + verb + ".xsd"); 559 } 560 return oai; 561 } 562 public static Element getMetadataPrefixElement(String tag_name, String version) { 563 //examples of tag_name: dc, oai_dc:dc, etc. 564 Element oai = response_doc.createElement(tag_name); 565 if (version.equals(OAI_VERSION2)) { 566 oai.setAttribute("xmlns:oai_dc", "http://www.openarchives.org/OAI/2.0/oai_dc/"); 567 oai.setAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/"); 568 oai.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 569 oai.setAttribute("xsi:schemaLocation", "http://www.openarchives.org/OAI/2.0/oai_dc/ \n http://www.openarchives.org/OAI/2.0/oai_dc.xsd"); 570 } else { 571 oai.setAttribute("xmlns", "ttp://www.openarchives.com/OAI/1.1/"); 572 oai.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); 573 oai.setAttribute("xsi:schemaLocation", "http://www.openarchives.org/OAI/1.1/" + tag_name + ".xsd"); 574 } 575 576 return oai; 577 } 578 public static HashMap<String, Node> getChildrenMapByTagName(Node n, String tag_name) { 579 579 580 581 582 583 580 HashMap<String, Node> map= new HashMap<String, Node>(); 581 Node child = n.getFirstChild(); 582 while (child!=null) { 583 String name = child.getNodeName(); 584 584 if(name.equals(tag_name)) { 585 586 } 587 588 589 590 591 592 593 594 595 596 597 598 599 Element element,600 String namespace_uri,601 boolean with_attributes) {602 603 604 605 606 607 608 609 610 611 612 613 614 615 585 map.put(name, child); 586 } 587 child = child.getNextSibling(); 588 } 589 return map; 590 } 591 592 /** Duplicates an element */ 593 public static Element duplicateElement (Document owner, Element element, boolean with_attributes) { 594 return duplicateElementNS (owner, element, null, with_attributes); 595 } 596 597 /** Duplicates an element */ 598 public static Element duplicateElementNS (Document owner, 599 Element element, 600 String namespace_uri, 601 boolean with_attributes) { 602 Element duplicate; 603 if (namespace_uri == null) { 604 duplicate = owner.createElement (element.getTagName ()); 605 } else { 606 duplicate = owner.createElementNS (namespace_uri, element.getTagName ()); 607 } 608 // Copy element attributes 609 if (with_attributes) { 610 NamedNodeMap attributes = element.getAttributes (); 611 for (int i = 0; i < attributes.getLength (); i++) { 612 Node attribute = attributes.item (i); 613 duplicate.setAttribute (attribute.getNodeName (), attribute.getNodeValue ()); 614 } 615 } 616 616 617 618 619 620 621 622 617 // Copy element children 618 NodeList children = element.getChildNodes (); 619 for (int i = 0; i < children.getLength (); i++) { 620 Node child = children.item (i); 621 duplicate.appendChild (owner.importNode (child, true)); 622 } 623 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 624 return duplicate; 625 } 626 627 public static void copyElement(Element to, Element from, String elem_name) { 628 629 Document to_doc = to.getOwnerDocument(); 630 Node child = from.getFirstChild(); 631 while (child != null) { 632 if (child.getNodeName().equals(elem_name)) { 633 to.appendChild(to_doc.importNode(child, true)); 634 return; 635 } 636 child = child.getNextSibling(); 637 } 638 } 639 640 public static HashMap<String, String> getParamMap(NodeList params) { 641 HashMap<String, String> map = new HashMap<String, String>(); 642 for(int i=0; i<params.getLength(); i++) { 643 Element param = (Element)params.item(i); 644 String param_name = param.getAttribute(OAIXML.NAME); 645 String param_value = param.getAttribute(OAIXML.VALUE); 646 map.put(param_name, param_value); 647 } 648 return map; 649 } 650 651 652 /** Parse an XML document from a given file */ 653 static public Document parseXMLFile (File xml_file) { 654 // No file? No point trying! 655 if (xml_file.exists () == false) { 656 return null; 657 } 658 Document doc = null; 659 try { 660 doc = parseXML (new FileInputStream (xml_file)); 661 } 662 catch (Exception exception) { 663 logger.error(exception.toString()); 664 return null; 665 } 666 return doc; 667 } 668 669 670 /** Parse an XML document from a given input stream */ 671 static public Document parseXML (InputStream xml_input_stream) { 672 Document document = null; 673 673 674 675 676 677 678 679 680 681 682 683 674 try { 675 InputStreamReader isr = new InputStreamReader (xml_input_stream, "UTF-8"); 676 Reader xml_reader = new BufferedReader (isr); 677 document = parseXML (xml_reader); 678 isr.close (); 679 xml_input_stream.close (); 680 } 681 catch (Exception exception) { 682 logger.error(exception.toString()); 683 } 684 684 685 686 687 688 689 690 685 return document; 686 } 687 688 /** Parse an XML document from a given reader */ 689 static public Document parseXML (Reader xml_reader) { 690 Document document = null; 691 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 692 try { 693 InputSource isc = new InputSource (xml_reader); 694 DOMParser parser = new DOMParser (); 695 parser.setFeature ("http://xml.org/sax/features/validation", false); 696 parser.setFeature ("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 697 // May or may not be ignored, the documentation for Xerces is contradictory. If it works then parsing -should- be faster. 698 parser.setFeature ("http://apache.org/xml/features/dom/defer-node-expansion", true); 699 parser.setFeature ("http://apache.org/xml/features/dom/include-ignorable-whitespace", false); 700 parser.parse (isc); 701 document = parser.getDocument (); 702 } 703 catch (SAXException exception) { 704 System.err.println ("SAX exception: " + exception.getMessage ()); 705 logger.error(exception.toString()); 706 } 707 catch (Exception exception) { 708 logger.error(exception.toString()); 709 } 710 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 711 return document; 712 } 713 /** Write an XML document to a given file */ 714 static public boolean writeXMLFile (File xml_file, Document document) { 715 try { 716 OutputStream os = new FileOutputStream (xml_file); 717 // Create an output format for our document. 718 OutputFormat f = new OutputFormat (document); 719 f.setEncoding ("UTF-8"); 720 f.setIndenting (true); 721 f.setLineWidth (0); // Why isn't this working! 722 f.setPreserveSpace (false); 723 // Create the necessary writer stream for serialization. 724 OutputStreamWriter osw = new OutputStreamWriter (os, "UTF-8"); 725 Writer w = new BufferedWriter (osw); 726 // Generate a new serializer from the above. 727 XMLSerializer s = new XMLSerializer (w, f); 728 s.asDOMSerializer (); 729 // Finally serialize the document to file. 730 s.serialize (document); 731 // And close. 732 os.close (); 733 return true; 734 } 735 catch (Exception exception) { 736 logger.error(exception.toString()); 737 return false; 738 } 739 } 740 740 741 741
Note:
See TracChangeset
for help on using the changeset viewer.