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
|
}
|