source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/XSLTServices.java@ 28966

Last change on this file since 28966 was 28966, checked in by kjdon, 10 years ago

Lots of changes. Mainly to do with removing this.doc from everywhere. Document is not thread safe. Now we tend to create a new Document everytime we are starting a new page/message etc. in service this.desc_doc is available as teh document to create service info stuff. But it should only be used for this and not for other messages. newDOM is now static for XMLConverter. method param changes for some GSXML methods.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 KB
Line 
1/*
2 * XSLTServices.java
3 * Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.service;
20
21import org.greenstone.gsdl3.util.*;
22import org.greenstone.gsdl3.selfContained.*;
23
24import javax.xml.transform.Source;
25import javax.xml.transform.Transformer;
26import javax.xml.transform.TransformerFactory;
27import javax.xml.transform.dom.DOMSource;
28import javax.xml.transform.stream.StreamResult;
29import org.apache.xerces.dom.DocumentImpl;
30import org.apache.xerces.dom.ElementImpl;
31import org.apache.xerces.dom.TextImpl;
32import org.w3c.dom.Document;
33import org.w3c.dom.Node;
34import org.w3c.dom.Text;
35import org.w3c.dom.Element;
36import org.w3c.dom.NodeList;
37
38import java.util.HashMap;
39import java.util.Vector;
40import java.util.Set;
41import java.util.Map;
42import java.util.Iterator;
43import java.util.Locale;
44import java.io.*;
45import java.net.URLEncoder;
46import java.net.URLDecoder;
47
48import org.apache.log4j.*;
49
50/**
51 * A ServiceRack class for XSLT query.
52 *
53 * Document ids are formed by encoding the document using standard URLEncoding
54 *
55 * @author Stuart Yeates
56 * @see ServiceRack
57 * @see java.net.URLEncoder
58 * @see java.net.URLDecoder
59 */
60
61public class XSLTServices
62 extends ServiceRack {
63
64 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.XSLTServices.class.getName());
65
66 // these strings must match what is found in the properties file
67 // the services on offer
68 private static final String XSLT_QUERY_SERVICE = "XSLTQuery";
69 private static final String RESOURCE_RETRIEVE_SERVICE = "ResourceRetrieve";
70 // params used
71 private static final String QUERY_PARAM = "query";
72 private static final String ALPHABET_PARAM = "alphabet";
73
74 private static final int RESULT_SET_SIZE = 10;
75
76 // alphabets
77 private static final String MINIMUM_ALPHABET = "minimum";
78 private static final String ASCII_ALPHABET = "ascii";
79 private static final String UNICODE_ALPHABET = "unicode";
80
81 private static final String DEFAULT_QUERY_STRING =
82 "<xsl:stylesheet version=\"1.0\""+
83 " xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"+
84 " <xsl:template match=\"*|/\">"+
85 " <xsl:apply-templates/>"+
86 " </xsl:template>"+
87 " <xsl:template match=\"*|/\" mode=\"m\">"+
88 " <xsl:apply-templates mode=\"m\"/>"+
89 " </xsl:template>"+
90 " <xsl:template match=\"text()|@*\">"+
91 " <xsl:value-of select=\".\"/>"+
92 " </xsl:template>"+
93 " <xsl:template match=\"processing-instruction()|comment()\"/>"+
94 "</xsl:stylesheet>";
95
96
97 private String alphabet = MINIMUM_ALPHABET;
98 private Element config_info_ = null;
99
100
101 public XSLTServices() {
102 }
103
104 /** configure this service */
105 public boolean configure(Element info, Element extra_info) {
106 if (!super.configure(info, extra_info)){
107 return false;
108 }
109
110 logger.info("configuring XSLTServices");
111 this.config_info = info;
112 try {
113 logger.info("called with:");
114 TransformerFactory transformerFactory = TransformerFactory.newInstance();
115 Element doc = GSXML.getFirstElementChild(info);//(Element)info.getFirstChild();
116 Transformer transformer = transformerFactory.newTransformer();
117 StreamResult result = new StreamResult(System.out);
118 Source source = new DOMSource(doc);
119 transformer.transform(source,result);
120 } catch (Throwable t) {
121 logger.error("Error printing XML in XSLTService::configure()");
122 }
123 return true;
124 }
125
126 protected Element getServiceDescription(Document doc, String service, String lang, String subset) {
127
128 return null;
129 }
130
131 /** process method for specific services - must be implemented by all
132 * subclasses
133 * should implement all services supported by the servicesImpl except
134 * for describe, which is implemented by this base class
135 *
136 */
137 protected Element processService(String service, Element request){
138 if (service.equals(XSLT_QUERY_SERVICE)) {
139 return processXSLTQuery(request);
140 } else if (service.equals(RESOURCE_RETRIEVE_SERVICE)) {
141 return processResourceRetrieve(request);
142 }
143 // create the response so we can report the error
144 Document result_doc = XMLConverter.newDOM();
145 Element response = result_doc.createElement(GSXML.RESPONSE_ELEM);
146 String from = GSPath.appendLink(this.cluster_name, RESOURCE_RETRIEVE_SERVICE);
147 response.setAttribute(GSXML.FROM_ATT, from);
148 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
149
150 logger.error("should never get here. service type wrong:"+service);
151 GSXML.addError(response,"XSLTServices:should never get here. service type wrong:"+service);
152 return response;
153 }
154
155 /** process a document resquest query */
156 protected Element processResourceRetrieve(Element request) {
157 Document result_doc = XMLConverter.newDOM();
158 // create the result and set the path so we know where we are
159 Element response = result_doc.createElement(GSXML.RESPONSE_ELEM);
160 String from = GSPath.appendLink(this.cluster_name, RESOURCE_RETRIEVE_SERVICE);
161 response.setAttribute(GSXML.FROM_ATT, from);
162 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
163
164 // get param list
165 Element param_elem=null;
166 Node n = request.getFirstChild();
167 while (n!=null) {
168 String node_name = n.getNodeName();
169 if (node_name.equals(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER)) {
170 param_elem = (Element)n;
171 break;
172 }
173 n = n.getNextSibling();
174 }
175
176 if (param_elem==null) {
177 logger.error("bad query request");
178 GSXML.addError(response,"bad query request in XSLTServices");
179 return response;
180 }
181
182 // Documents are just the ids decoding using standard URL decoding
183
184 Element doc_list = (Element)GSXML.getChildByTagName(request, GSXML.DOCUMENT_ELEM+GSXML.LIST_MODIFIER);
185 String []ids = GSXML.getAttributeValuesFromList(doc_list, GSXML.NAME_ATT);
186 for (int j=0; j<ids.length; j++) {
187 String document = null;
188 try {
189 document = URLDecoder.decode(ids[j],"UTF-8");
190 } catch (UnsupportedEncodingException e) {
191 throw new Error(e.toString());
192 }
193 // something funny with the doc -
194 Element new_doc = result_doc.createElement(GSXML.DOCUMENT_ELEM);
195 new_doc.setAttribute(GSXML.NAME_ATT, ids[j]); //GSXML.createDocumentElement(this.doc, ids[j]);
196 GSXML.addDocText(new_doc, document);
197 response.appendChild(new_doc);
198 }
199
200 return response;
201 }
202
203 /** process a XSLT query */
204 protected Element processXSLTQuery(Element request) {
205 Document result_doc = XMLConverter.newDOM();
206 // create the result and set the path so we know where we are
207 Element response = result_doc.createElement(GSXML.RESPONSE_ELEM);
208 String from = GSPath.appendLink(this.cluster_name, XSLT_QUERY_SERVICE);
209 response.setAttribute(GSXML.FROM_ATT, from);
210 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
211
212 // get the parameter list
213 Element param_list =
214 (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
215
216 // extract the only parameter we care about
217 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
218 String query = (String)params.get(QUERY_PARAM);
219
220 if (query == null || query.equals(""))
221 query = DEFAULT_QUERY_STRING;
222
223
224 DocumentStream stream = null;
225 if (alphabet.equals(MINIMUM_ALPHABET)){
226 stream = new GeneratedDocumentStream('a','c');
227 } else if(alphabet.equals(ASCII_ALPHABET)){
228 stream = new GeneratedDocumentStream();
229 } else if(alphabet.equals(UNICODE_ALPHABET)){
230 stream = new GeneratedDocumentStream(Character.MIN_VALUE,
231 Character.MAX_VALUE);
232 } else {
233 logger.error("bad alphabet name : "+ alphabet);
234 GSXML.addError(response,"XSLTServices: bad alphabet name : "+ alphabet);
235 stream = new GeneratedDocumentStream();
236 }
237
238 Element resource_list = result_doc.createElement(GSXML.RESOURCE_ELEM+GSXML.LIST_MODIFIER);
239 response.appendChild(resource_list);
240
241 // Framework to stringise the document
242 TransformerFactory transformerFactory = TransformerFactory.newInstance();
243
244 // add each resource
245 for (int d=0; d<RESULT_SET_SIZE; d++) {
246 try {
247 Document document = stream.nextDocument();
248 Element doc = GSXML.getFirstElementChild(document);//(Element)document.getFirstChild();
249 Transformer transformer = transformerFactory.newTransformer();
250 StringWriter writer = new StringWriter();
251 StreamResult result = new StreamResult(writer);
252 Source source = new DOMSource(doc);
253 transformer.transform(source,result);
254 String id = writer.toString();
255 Element e = result_doc.createElement(GSXML.DOCUMENT_ELEM);
256 e.setAttribute(GSXML.NAME_ATT, id);
257 //Node no = GSXML.createDocumentElement(this.doc, id);
258 resource_list.appendChild(e);
259 } catch (Throwable t) {
260 GSXML.addError(response, "Error in XSLTServices finding results:" + t.toString());
261 }
262 }
263 return response;
264 }
265}
266
267
Note: See TracBrowser for help on using the repository browser.