Revision 3321
Added by barteau over 17 years ago
src/edu/ucsb/nceas/metacat/clientview/ClientFgdcHelper.java | ||
---|---|---|
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 |
} |
|
0 | 282 |
Also available in: Unified diff
Initial checkin. The "Client View FGDC Helper", to provide FGDC specific methods for client views. This is an API class for the clientview package.