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 com.oreilly.servlet.multipart.MultipartParser;
13
import edu.ucsb.nceas.metacat.client.MetacatException;
14
import edu.ucsb.nceas.utilities.XMLUtilities;
15
import java.io.BufferedReader;
16
import java.io.IOException;
17
import java.io.InputStream;
18
import java.io.Reader;
19
import java.io.StringReader;
20
import java.util.HashMap;
21
import java.util.Iterator;
22
import java.util.Properties;
23
import javax.xml.xpath.XPath;
24
import javax.xml.xpath.XPathConstants;
25
import javax.xml.xpath.XPathExpressionException;
26
import javax.xml.xpath.XPathFactory;
27
import org.w3c.dom.Document;
28
import org.w3c.dom.DocumentType;
29
import org.w3c.dom.Node;
30
import org.w3c.dom.NodeList;
31

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