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