Project

General

Profile

1
/*
2
 * ClientFgdcHelper.java
3
 *
4
 * Created on June 25, 2007, 9:58 AM
5
 *
6
 * To change this template, choose Tools | Template Manager
7
 * and open the template in the editor.
8
 */
9

    
10
package edu.ucsb.nceas.metacat.clientview;
11

    
12
import edu.ucsb.nceas.metacat.client.MetacatException;
13
import edu.ucsb.nceas.utilities.XMLUtilities;
14
import java.io.IOException;
15
import java.io.InputStream;
16
import java.io.Reader;
17
import java.io.StringReader;
18
import java.util.HashMap;
19
import java.util.Iterator;
20
import java.util.Properties;
21
import javax.xml.xpath.XPath;
22
import javax.xml.xpath.XPathConstants;
23
import javax.xml.xpath.XPathExpressionException;
24
import javax.xml.xpath.XPathFactory;
25
import org.w3c.dom.Document;
26
import org.w3c.dom.DocumentType;
27
import org.w3c.dom.Node;
28
import org.w3c.dom.NodeList;
29

    
30
/**
31
 *
32
 * @author barteau
33
 */
34
public abstract class ClientFgdcHelper {
35
    
36
    private static XPath                    xpath = XPathFactory.newInstance().newXPath();
37
    
38
    /**
39
     * Data Document ID location within an FGDC document.  XPath expression.
40
     */
41
    public static final String              FGDC_DATA_FILE_DOCID_XPATH = "/metadata/distinfo/stdorder/digform/digtopt/onlinopt/computer/networka/networkr";
42
    public static final String              FGDC_DATA_FILE_QUERY_XPATH = FGDC_DATA_FILE_DOCID_XPATH + "[text()='%1s']";
43
    public static final String              FGDC_DATA_FILE_NAME_XPATH = "digtinfo/formcont";
44
    
45
    /**
46
     * FGDC Data Document ID location within an FGDC document, relative to the "distinfo" parent node.
47
     * XPath expression.
48
     */
49
    public static final String              FGDC_DATA_FILE_NODES_XPATH = "stdorder/digform/digtopt/onlinopt/computer/networka/networkr";
50
    
51
    public static final String              PATH4ANCESTOR = FGDC_DATA_FILE_DOCID_XPATH + "[text()='%1s']/ancestor::node()[name()='%2s']";
52
    public static final String              SUB_DOCS_PATH = FGDC_DATA_FILE_DOCID_XPATH + "/text()";
53
    
54
    /**
55
     * Metadata Document ID location within an FGDC document.  XPath expression.
56
     */
57
    public static final String              FGDC_DOCID_XPATH = "/metadata/distinfo/resdesc";
58
    public static final String              FGDC_FILE_NAME_XPATH = "custom";
59
    /**
60
     * Metadata Document ID query template within an FGDC document.  Substitute %1s with Doc Id.
61
     */
62
    public static final String              XPATH_QUERY_TEMPLATE = FGDC_DOCID_XPATH + "[text()='%1s']";
63
    public static final String              FGDC_DOCID_ROOT_XPATH = XPATH_QUERY_TEMPLATE + "/ancestor::node()[name()='distinfo']";
64
    
65
    /**
66
     * Identifies the FGDC DTD.
67
     */
68
    public static final String              FGDC_SYSTEM_ID = "http://www.fgdc.gov/metadata/fgdc-std-001-1998.dtd";
69
    
70
    /**
71
     * Handles a client's request to delete a document.
72
     * If its a data document, it removes the Doc Id from the FGDC metadata in the
73
     * Metacat database.  It determines what metadata Doc ID is including this Doc Id.
74
     * It then queries metacat for the parent FGDC document and removes the Doc Id from it, and
75
     * reloads the new version with a new revision number.
76
     * If its a metadata document, it deletes any related data documents, then it
77
     * deletes the metadata.  In either instance, it sets the server feedback in
78
     * the session ("updateFeedback").
79
     * @param request HttpServletRequest which contains docId parameter.
80
     */
81
    public static void clientDeleteRequest(ClientView clientViewBean, ClientViewHelper clientViewHelper) {
82
        String                      result = null, docId, subDocId, parentDocId, revisedDocId;
83
        NodeList                    nodeLst;
84
        Node                        node;
85
        Document                    resultSetDoc;
86
        
87
        docId = clientViewBean.getDocId();
88
        try {
89
            //*** First, determine what metadata file is including this file (if any).
90
            resultSetDoc = clientViewHelper.query(FGDC_DATA_FILE_DOCID_XPATH, docId, null);
91
            parentDocId = xpath.evaluate("/resultset/document/docid", resultSetDoc.getDocumentElement());
92
            if (parentDocId != null && !parentDocId.equals("")) {
93
                clientViewHelper.setMetadataDoc(parentDocId);
94
                //*** Remove Doc Id from any parent metadata document.
95
                revisedDocId = removeDataDocIdFromFGDC(docId, parentDocId, clientViewHelper);
96
                clientViewBean.setDocId(revisedDocId);
97
                //*** Set the new Metadata Doc Id in the bean.
98
                clientViewBean.setMetaFileDocId(revisedDocId);
99
            } else {
100
                clientViewHelper.setMetadataDoc(docId);
101
                //*** This is a metadata document, so remove all of the sub-docId's.
102
                nodeLst = (NodeList) xpath.evaluate(SUB_DOCS_PATH, clientViewHelper.getMetadataDoc().getDocumentElement(), XPathConstants.NODESET);
103
                for(int i = 0; i < nodeLst.getLength(); i++) {
104
                    node = nodeLst.item(i);
105
                    subDocId = node.getNodeValue();
106
                    //*** Remove the sub-document.
107
                    try {
108
                        clientViewHelper.getMetacatClient().delete(subDocId);
109
                    } catch (MetacatException ex) {
110
                        ex.printStackTrace();
111
                    }
112
                }
113
                //*** We're deleting the Meta data doc, so clear it from the bean.
114
                clientViewBean.setMetaFileDocId(null);
115
            }
116
            //*** Remove the document.
117
            result = clientViewHelper.getMetacatClient().delete(docId);
118
            
119
            //*** Save the server feedback in the session, to be used by the view.
120
            clientViewBean.setMessage(ClientView.DELETE_MESSAGE, result);
121
        } catch (Exception ex) {
122
            ex.printStackTrace();
123
        }
124
    }
125
    
126
    private static String removeDataDocIdFromFGDC(String docId, String parentDocId, ClientViewHelper clientViewHelper) throws Exception {
127
        String                          pathToDigform, revision = "", xPathQuery, tmp;
128
        Document                        doc;
129
        InputStream                     response;
130
        Properties                      prop;
131
        Node                            node;
132
        NodeList                        nodeLst;
133
        Reader                          reader;
134
        
135
        //*** Get the metadata document and remove the digform branch.
136
        doc = clientViewHelper.getMetadataDoc();
137
        if (doc != null) {
138
            tmp = PATH4ANCESTOR.replaceFirst("%1s", docId);
139
            pathToDigform = tmp.replaceFirst("%2s", "digform");
140
            node = (Node) xpath.evaluate(pathToDigform, doc.getDocumentElement(), XPathConstants.NODE);
141
            node.getParentNode().removeChild(node);
142
            xPathQuery = XPATH_QUERY_TEMPLATE.replaceFirst("%1s", parentDocId);
143
            revision = clientViewHelper.nextVersion(parentDocId, xPathQuery);
144
            reader = XMLUtilities.getDOMTreeAsReader(doc.getDocumentElement(), false);
145
            clientViewHelper.getMetacatClient().update(revision, reader, null);
146
        }
147
        return(revision);
148
    }
149
    
150
    public static boolean handlePackageUpload(String metaDocId,
151
            HashMap dataDocIDs,
152
            String contactName,
153
            String metaFNm,
154
            Document metadataDoc) throws IOException {
155
        boolean                         result = true;
156
        Node                            newBranch, metaRootNode;
157
        
158
        //*** Store the User Name and Doc Id in the FGDC document.
159
        newBranch = getFGDCdisinfo(contactName, metaDocId, metaFNm, dataDocIDs);
160
        //System.out.println("ClientFgdcHelper.handlePackageUpload: " + XMLUtilities.getDOMTreeAsString(newBranch));
161
        metaRootNode = addDistInfoToFGDC(newBranch, metadataDoc);
162
        return(result);
163
    }
164
    
165
    
166
    public static boolean isFGDC(Document metadataDoc) {
167
        boolean                     result = false;
168
        DocumentType                docType;
169
        String                      sysId;
170
        final String                FGDC_TEST_EXPRESSION = "/metadata/idinfo/citation/citeinfo/title";
171
        Node                        node = null;
172
        
173
        //*** First, try the rigid proper way of determining it.
174
        if (metadataDoc != null) {
175
            docType = metadataDoc.getDoctype();
176
            if (docType != null) {
177
                sysId = docType.getSystemId();
178
                if (sysId != null)
179
                    result = (sysId.indexOf(FGDC_SYSTEM_ID) > -1);
180
            }
181
        }
182
        //*** It might not have a doc type line, so try another method.
183
        if (metadataDoc != null && !result) {
184
            try {
185
                node = (Node) xpath.evaluate(FGDC_TEST_EXPRESSION, metadataDoc.getDocumentElement(), XPathConstants.NODE);
186
            } catch (XPathExpressionException ex) {
187
                ex.printStackTrace();
188
            }
189
            result = (node != null);
190
        }
191
        return(result);
192
    }
193
    
194
    public static boolean hasMetacatInfo(String docId, Document metadataDoc) {
195
        boolean                     result = false;
196
        String                      queryResult, xPathQuery;
197
        
198
        //xPathQuery = String.format(XPATH_QUERY_TEMPLATE, docId);
199
        xPathQuery = XPATH_QUERY_TEMPLATE.replaceFirst("%1s", docId);
200
        try {
201
            queryResult = xpath.evaluate(xPathQuery, metadataDoc);
202
            result = (queryResult != null && !queryResult.equals(""));
203
        } catch (XPathExpressionException ex) {
204
            ex.printStackTrace();
205
        }
206
        return(result);
207
    }
208
    
209
    private static Node getFGDCdisinfo(String contactName, String resourceDescription, String metaFNm, HashMap dataDocIDs) throws IOException {
210
        Node                        result = null, node, digformBranch, formname, stdorder, formcont;
211
        Document                    doc;
212
        Iterator                    iterIt;
213
        String                      key, value, fileInfo[];
214
        
215
        //*** This is a valid/minimal FGDC "distinfo" branch.
216
        final String XML = "<distinfo>"
217
                + "    <distrib>"
218
                + "        <cntinfo>"
219
                + "            <cntperp>"
220
                + "                <cntper></cntper>"
221
                + "            </cntperp>"
222
                + "            <cntaddr>"
223
                + "                <addrtype></addrtype>"
224
                + "                <address></address>"
225
                + "                <city></city>"
226
                + "                <state></state>"
227
                + "                <postal></postal>"
228
                + "                <country></country>"
229
                + "            </cntaddr>"
230
                + "            <cntvoice></cntvoice>"
231
                + "        </cntinfo>"
232
                + "    </distrib>"
233
                + "    <resdesc></resdesc>"
234
                + "    <distliab></distliab>"
235
                + "    <stdorder>"
236
                + "        <digform>"
237
                + "            <digtinfo>"
238
                + "                <formname></formname>"
239
                + "                <formcont></formcont>"
240
                + "            </digtinfo>"
241
                + "            <digtopt>"
242
                + "                <onlinopt>"
243
                + "                    <computer>"
244
                + "                        <networka>"
245
                + "                            <networkr></networkr>"
246
                + "                        </networka>"
247
                + "                    </computer>"
248
                + "                </onlinopt>"
249
                + "            </digtopt>"
250
                + "        </digform>"
251
                + "        <fees></fees>"
252
                + "    </stdorder>"
253
                + "    <custom></custom>"
254
                + "</distinfo>";
255
        
256
        doc = XMLUtilities.getXMLReaderAsDOMDocument(new StringReader(XML));
257
        result = doc.getDocumentElement();
258
        try {
259
            //*** Set the Contact Person.
260
            node = (Node) xpath.evaluate("/distinfo/distrib/cntinfo/cntperp/cntper", result, XPathConstants.NODE);
261
            ClientViewHelper.setTextContent(xpath, node, contactName);
262
            //node.setTextContent(contactName);  Not in java 1.4
263
            
264
            //*** Set the metadata Doc Id.
265
            node = (Node) xpath.evaluate("/distinfo/resdesc", result, XPathConstants.NODE);
266
            ClientViewHelper.setTextContent(xpath, node, resourceDescription);
267
            //node.setTextContent(resourceDescription);  Not in java 1.4
268
            
269
            //*** Set the metadata filename.
270
            node = (Node) xpath.evaluate("/distinfo/custom", result, XPathConstants.NODE);
271
            ClientViewHelper.setTextContent(xpath, node, metaFNm);
272
            //node.setTextContent(metaFNm);  Not in java 1.4
273
            
274
            //*** Loop thru the files, setting their format and Doc Id.
275
            stdorder = (Node) xpath.evaluate("/distinfo/stdorder", result, XPathConstants.NODE);
276
            digformBranch = (Node) xpath.evaluate("/distinfo/stdorder/digform", result, XPathConstants.NODE);
277
            iterIt = dataDocIDs.keySet().iterator();
278
            while(iterIt.hasNext()) {
279
                //*** Save the data file Doc ID (required).
280
                key = (String) iterIt.next();
281
                node = (Node) xpath.evaluate("digtopt/onlinopt/computer/networka/networkr", digformBranch, XPathConstants.NODE);
282
                ClientViewHelper.setTextContent(xpath, node, key);
283
                //node.setTextContent(key);
284
                
285
                fileInfo = (String[]) dataDocIDs.get(key);
286
                if (fileInfo != null) {
287
                    //*** Save the data file format (optional).
288
                    formname = (Node) xpath.evaluate("digtinfo/formname", digformBranch, XPathConstants.NODE);
289
                    if ((value = fileInfo[ClientView.FORMAT_TYPE]) != null && !value.equals("")) {
290
                        ClientViewHelper.setTextContent(xpath, formname, value);
291
                        //formname.setTextContent(value);
292
                    } else {
293
                        //*** We did a deep clone of the branch, so clear prior contents.
294
                        ClientViewHelper.setTextContent(xpath, formname, "");
295
                        //formname.setTextContent("");
296
                    }
297
                    //*** Save the data file name.
298
                    formcont = (Node) xpath.evaluate("digtinfo/formcont", digformBranch, XPathConstants.NODE);
299
                    if ((value = fileInfo[ClientView.FILE_NAME]) != null && !value.equals("")) {
300
                        ClientViewHelper.setTextContent(xpath, formcont, value);
301
                        //formcont.setTextContent(value);
302
                    } else {
303
                        //*** We did a deep clone of the branch, so clear prior contents.
304
                        ClientViewHelper.setTextContent(xpath, formcont, "");
305
                        //formcont.setTextContent("");
306
                    }
307
                }
308
                //*** Clone branch for next file.
309
                if (iterIt.hasNext()) {
310
                    digformBranch = digformBranch.cloneNode(true);
311
                    stdorder.appendChild(digformBranch);
312
                }
313
            }
314
        } catch (XPathExpressionException ex) {
315
            ex.printStackTrace();
316
        }
317
        return(result);
318
    }
319
    
320
    private static Node addDistInfoToFGDC(Node newBranch, Document metadataDoc) {
321
        Node                        result = null, node;
322
        
323
        if (newBranch != null) {
324
            result = metadataDoc.getDocumentElement();
325
            try {
326
                //*** Get a reference to the FGDC required "metainfo" node (only 1 allowed).
327
                node = (Node) xpath.evaluate("/metadata/metainfo", result, XPathConstants.NODE);
328
                if (node != null) {
329
                    newBranch = metadataDoc.importNode(newBranch, true);
330
                    //*** Add the new "distinfo" before it.
331
                    result.insertBefore(newBranch, node);
332
                }
333
            } catch (XPathExpressionException ex) {
334
                ex.printStackTrace();
335
            }
336
        }
337
        return(result);
338
    }
339
    
340
    public static void updateFileNameAndType(Node root, String dataDocId, String[] fileInfo) {
341
        Node                digform;
342
        String              tmp, pathToDigform;
343
        final String        FORMNAME_PATH = "digtinfo/formname";  //*** File format type.
344
        final String        FORMCONT_PATH = "digtinfo/formcont";  //*** Original file name.
345
        
346
        tmp = PATH4ANCESTOR.replaceFirst("%1s", dataDocId);
347
        pathToDigform = tmp.replaceFirst("%2s", "digform");
348
        digform = ClientViewHelper.getNode(xpath, pathToDigform, root);
349
        if (digform != null) {
350
            ClientViewHelper.updateNodeText(digform, xpath, FORMNAME_PATH, fileInfo[ClientView.FORMAT_TYPE]);
351
            ClientViewHelper.updateNodeText(digform, xpath, FORMCONT_PATH, fileInfo[ClientView.FILE_NAME]);
352
        }
353
    }
354
    
355
    public static void updateMetadataFileName(Node root, String metadataDocId, String fileName) {
356
        String                  pathToResdesc;
357
        Node                    resdesc;
358
        
359
        if (fileName != null && !fileName.equals("")) {
360
            pathToResdesc = XPATH_QUERY_TEMPLATE.replaceFirst("%1s", metadataDocId);
361
            ClientViewHelper.updateNodeText(root, xpath, pathToResdesc, metadataDocId);
362
        }
363
    }
364
}
(1-1/5)