Project

General

Profile

1
/**
2
 * Copyright 2006 OCLC Online Computer Library Center Licensed under the Apache
3
 * License, Version 2.0 (the "License"); you may not use this file except in
4
 * compliance with the License. You may obtain a copy of the License at
5
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or
6
 * agreed to in writing, software distributed under the License is distributed on
7
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
8
 * or implied. See the License for the specific language governing permissions and
9
 * limitations under the License.
10
 */
11
package edu.ucsb.nceas.metacat.oaipmh.provider.server.crosswalk;
12

    
13
import java.io.FileInputStream;
14
import java.io.StringReader;
15
import java.io.StringWriter;
16
import java.util.HashMap;
17
import java.util.Properties;
18

    
19
import javax.xml.transform.Transformer;
20
import javax.xml.transform.TransformerFactory;
21
import javax.xml.transform.stream.StreamResult;
22
import javax.xml.transform.stream.StreamSource;
23

    
24
import org.apache.log4j.Logger;
25

    
26
import ORG.oclc.oai.server.crosswalk.Crosswalk;
27
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
28
import ORG.oclc.oai.server.verb.OAIInternalServerError;
29

    
30

    
31
/**
32
 * Provides EML documents in eml-2.1.0 format. For eml-2.1.0 documents, we
33
 * simply return the metadata that was read from Metacat. For eml-2.0.x
34
 * documents, we use the EML Utilities stylesheet to transform the document
35
 * to eml-2.1.0.
36
 */
37
public class Eml extends Crosswalk {
38
  
39
  /* Class fields */
40

    
41
  private static final Logger logger = Logger.getLogger(Eml.class);
42
  private static String dirPath = null;
43
  
44
  // This is a local copy of the stylesheet from the EML Utilities module
45
  private static final String XSLT_NAME = "eml201to210.xsl";
46
  
47
  private static final String SCHEMA_LOCATION =
48
    "eml://ecoinformatics.org/eml-2.1.0 " +
49
    "http://knb.ecoinformatics.org/knb/schema/eml-2.1.0/eml.xsd";
50

    
51

    
52
  /* Instance fields */
53
  
54
  private Transformer transformer = null;
55
  
56
  
57
  /* Constructors */
58

    
59
  /**
60
   * The constructor assigns the schemaLocation associated with this crosswalk.
61
   * Since the crosswalk is trivial in this case, no properties are utilized.
62
   * 
63
   * @param properties
64
   *          properties that are needed to configure the crosswalk.
65
   */
66
  public Eml(Properties properties) throws OAIInternalServerError {
67
    super(SCHEMA_LOCATION);
68
    String xsltPath = dirPath + "/" + XSLT_NAME;
69
    
70
    try {
71
      TransformerFactory tFactory = TransformerFactory.newInstance();
72
      FileInputStream fileInputStream = new FileInputStream(xsltPath);
73
      StreamSource xslSource = new StreamSource(fileInputStream);
74
      this.transformer = tFactory.newTransformer(xslSource);
75
    } 
76
    catch (Exception e) {
77
      e.printStackTrace();
78
      throw new OAIInternalServerError(e.getMessage());
79
    }
80
  }
81
  
82
  
83
  /* Class methods */
84
  
85
  /**
86
   * Set the value of the configuration directory path so that XSLT stylesheets
87
   * can be located on the system.
88
   * 
89
   * @param configDir   the configuration directory path
90
   */
91
  public static void setDirPath(String configDir) {
92
    Eml.dirPath = configDir;
93
  }
94

    
95

    
96
  
97
  /* Instance methods */
98

    
99

    
100
  /**
101
   * Perform the actual crosswalk.
102
   * 
103
   * @param nativeItem  A HashMap object that contains the EML string that was
104
   *                    retrieved from Metacat and stored as the value of the
105
   *                    "recordBytes" key
106
   * @return eml210doc  a String containing the metadata to be stored within 
107
   *                    the <metadata> element in eml 2.1.0 format
108
   * @exception CannotDisseminateFormatException
109
   *              nativeItem doesn't support this format.
110
   */
111
  public String createMetadata(Object nativeItem)
112
      throws CannotDisseminateFormatException {
113
    HashMap recordMap = (HashMap) nativeItem;
114
    String eml210doc = null;
115
    
116
    String docid = (String) recordMap.get("localIdentifier");
117
    String doctype = (String) recordMap.get("doctype");
118
    String xmlRec = (String) recordMap.get("recordBytes");
119

    
120
    /* Transform eml-2.0.x documents to eml-2.1.0 using the stylesheet from
121
     * the EML Utilities module 
122
     */
123
    if ((doctype != null) && (doctype.contains("eml-2.0.0") ||
124
                              doctype.contains("eml-2.0.1")
125
                             )
126
       ) 
127
    {
128
      if (docid != null) {
129
        logger.debug("Transforming " + doctype + " document, " + docid + ", to eml-2.1.0.");
130
      }
131
      
132
      try {
133
        StringReader stringReader = new StringReader(xmlRec);
134
        StreamSource streamSource = new StreamSource(stringReader);
135
        StringWriter stringWriter = new StringWriter();
136
        
137
        synchronized (transformer) {
138
          transformer.transform(streamSource, new StreamResult(stringWriter));
139
        }
140
        eml210doc = stringWriter.toString();
141
      } 
142
      catch (Exception e) {
143
        throw new CannotDisseminateFormatException(e.getMessage());
144
      }
145
    }
146
    else if (xmlRec.contains("eml://ecoinformatics.org/eml-2.1.0")) {
147
        eml210doc = xmlRec;
148
    }
149
    
150
    eml210doc = eml210doc.trim();
151
    
152
    /*
153
     * Remove the lead xml processing instruction because the document is going
154
     * to be placed inside an OAI <metadata> element within a 
155
     */
156
    if (eml210doc.startsWith("<?")) {
157
      int offset = eml210doc.indexOf("?>");
158
      eml210doc = eml210doc.substring(offset + 2);
159
    }
160
      
161
    return eml210doc;
162
  }
163
  
164
  
165
  /**
166
   * Can this nativeItem be represented in 'eml' format?
167
   * 
168
   * @param nativeItem              a record in native format
169
   * @return true if 'eml' format is possible, false otherwise.
170
   */
171
  public boolean isAvailableFor(Object nativeItem) {
172
    // We assume that all EML documents can be represented in eml format
173
    return true;
174
  }
175
  
176
}
(1-1/2)