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

Last change on this file since 25635 was 25635, checked in by sjm84, 12 years ago

Fixing Greenstone 3's use (or lack thereof) of generics, this was done automatically so we may want to change it over time. This change will also auto-format any files that have not already been formatted.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.6 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 <a href="mailto:[email protected]">Katherine Don</a>
56 * @author <a href="mailto:[email protected]">Stuart Yeates</a>
57 * @version $Revision: 25635 $
58 * @see ServiceRack
59 * @see java.net.URLEncoder
60 * @see java.net.URLDecoder
61 */
62
63public class XSLTServices
64 extends ServiceRack {
65
66 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.XSLTServices.class.getName());
67
68 // these strings must match what is found in the properties file
69 // the services on offer
70 private static final String XSLT_QUERY_SERVICE = "XSLTQuery";
71 private static final String RESOURCE_RETRIEVE_SERVICE = "ResourceRetrieve";
72 // params used
73 private static final String QUERY_PARAM = "query";
74 private static final String ALPHABET_PARAM = "alphabet";
75
76 private static final int RESULT_SET_SIZE = 10;
77
78 // alphabets
79 private static final String MINIMUM_ALPHABET = "minimum";
80 private static final String ASCII_ALPHABET = "ascii";
81 private static final String UNICODE_ALPHABET = "unicode";
82
83 private static final String DEFAULT_QUERY_STRING =
84 "<xsl:stylesheet version=\"1.0\""+
85 " xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"+
86 " <xsl:template match=\"*|/\">"+
87 " <xsl:apply-templates/>"+
88 " </xsl:template>"+
89 " <xsl:template match=\"*|/\" mode=\"m\">"+
90 " <xsl:apply-templates mode=\"m\"/>"+
91 " </xsl:template>"+
92 " <xsl:template match=\"text()|@*\">"+
93 " <xsl:value-of select=\".\"/>"+
94 " </xsl:template>"+
95 " <xsl:template match=\"processing-instruction()|comment()\"/>"+
96 "</xsl:stylesheet>";
97
98
99 private String alphabet = MINIMUM_ALPHABET;
100 private Element config_info_ = null;
101
102
103 public XSLTServices() {
104 }
105
106 /** configure this service */
107 public boolean configure(Element info, Element extra_info) {
108 if (!super.configure(info, extra_info)){
109 return false;
110 }
111
112 logger.info("configuring XSLTServices");
113 this.config_info = info;
114 try {
115 logger.info("called with:");
116 TransformerFactory transformerFactory = TransformerFactory.newInstance();
117 Element doc = GSXML.getFirstElementChild(info);//(Element)info.getFirstChild();
118 Transformer transformer = transformerFactory.newTransformer();
119 StreamResult result = new StreamResult(System.out);
120 Source source = new DOMSource(doc);
121 transformer.transform(source,result);
122 } catch (Throwable t) {
123 logger.error("Error printing XML in XSLTService::configure()");
124 }
125 return true;
126 }
127
128 protected Element getServiceDescription(String service, String lang, String subset) {
129
130 return null;
131 }
132
133 /** process method for specific services - must be implemented by all
134 * subclasses
135 * should implement all services supported by the servicesImpl except
136 * for describe, which is implemented by this base class
137 *
138 */
139 protected Element processService(String service, Element request){
140 if (service.equals(XSLT_QUERY_SERVICE)) {
141 return processXSLTQuery(request);
142 } else if (service.equals(RESOURCE_RETRIEVE_SERVICE)) {
143 return processResourceRetrieve(request);
144 }
145 // create the response so we can report the error
146 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
147 String from = GSPath.appendLink(this.cluster_name, RESOURCE_RETRIEVE_SERVICE);
148 response.setAttribute(GSXML.FROM_ATT, from);
149 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
150
151 logger.error("should never get here. service type wrong:"+service);
152 GSXML.addError(this.doc, response,"XSLTServices:should never get here. service type wrong:"+service);
153 return response;
154 }
155
156 /** process a document resquest query */
157 protected Element processResourceRetrieve(Element request) {
158
159 // create the result and set the path so we know where we are
160 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
161 String from = GSPath.appendLink(this.cluster_name, RESOURCE_RETRIEVE_SERVICE);
162 response.setAttribute(GSXML.FROM_ATT, from);
163 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
164
165 // get param list
166 Element param_elem=null;
167 Node n = request.getFirstChild();
168 while (n!=null) {
169 String node_name = n.getNodeName();
170 if (node_name.equals(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER)) {
171 param_elem = (Element)n;
172 break;
173 }
174 n = n.getNextSibling();
175 }
176
177 if (param_elem==null) {
178 logger.error("bad query request");
179 GSXML.addError(this.doc, response,"bad query request in XSLTServices");
180 return response;
181 }
182
183 // Documents are just the ids decoding using standard URL decoding
184
185 Element doc_list = (Element)GSXML.getChildByTagName(request, GSXML.DOCUMENT_ELEM+GSXML.LIST_MODIFIER);
186 String []ids = GSXML.getAttributeValuesFromList(doc_list, GSXML.NAME_ATT);
187 for (int j=0; j<ids.length; j++) {
188 String document = null;
189 try {
190 document = URLDecoder.decode(ids[j],"UTF-8");
191 } catch (UnsupportedEncodingException e) {
192 throw new Error(e.toString());
193 }
194 // something funny with the doc -
195 Element new_doc = this.doc.createElement(GSXML.DOCUMENT_ELEM);
196 new_doc.setAttribute(GSXML.NAME_ATT, ids[j]); //GSXML.createDocumentElement(this.doc, ids[j]);
197 GSXML.addDocText(this.doc, new_doc, document);
198 response.appendChild(new_doc);
199 }
200
201 return response;
202 }
203
204 /** process a XSLT query */
205 protected Element processXSLTQuery(Element request) {
206
207 // create the result and set the path so we know where we are
208 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
209 String from = GSPath.appendLink(this.cluster_name, XSLT_QUERY_SERVICE);
210 response.setAttribute(GSXML.FROM_ATT, from);
211 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
212
213 // get the parameter list
214 Element param_list =
215 (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
216
217 // extract the only parameter we care about
218 HashMap<String, Serializable> params = GSXML.extractParams(param_list, false);
219 String query = (String)params.get(QUERY_PARAM);
220
221 if (query == null || query.equals(""))
222 query = DEFAULT_QUERY_STRING;
223
224
225 DocumentStream stream = null;
226 if (alphabet.equals(MINIMUM_ALPHABET)){
227 stream = new GeneratedDocumentStream('a','c');
228 } else if(alphabet.equals(ASCII_ALPHABET)){
229 stream = new GeneratedDocumentStream();
230 } else if(alphabet.equals(UNICODE_ALPHABET)){
231 stream = new GeneratedDocumentStream(Character.MIN_VALUE,
232 Character.MAX_VALUE);
233 } else {
234 logger.error("bad alphabet name : "+ alphabet);
235 GSXML.addError(this.doc, response,"XSLTServices: bad alphabet name : "+ alphabet);
236 stream = new GeneratedDocumentStream();
237 }
238
239 Element resource_list = this.doc.createElement(GSXML.RESOURCE_ELEM+GSXML.LIST_MODIFIER);
240 response.appendChild(resource_list);
241
242 // Framework to stringise the document
243 TransformerFactory transformerFactory = TransformerFactory.newInstance();
244
245 // add each resource
246 for (int d=0; d<RESULT_SET_SIZE; d++) {
247 try {
248 Document document = stream.nextDocument();
249 Element doc = GSXML.getFirstElementChild(document);//(Element)document.getFirstChild();
250 Transformer transformer = transformerFactory.newTransformer();
251 StringWriter writer = new StringWriter();
252 StreamResult result = new StreamResult(writer);
253 Source source = new DOMSource(doc);
254 transformer.transform(source,result);
255 String id = writer.toString();
256 Element e = this.doc.createElement(GSXML.DOCUMENT_ELEM);
257 e.setAttribute(GSXML.NAME_ATT, id);
258 //Node no = GSXML.createDocumentElement(this.doc, id);
259 resource_list.appendChild(e);
260 } catch (Throwable t) {
261 GSXML.addError(this.doc, response, "Error in XSLTServices finding results:" + t.toString());
262 }
263 }
264 return response;
265 }
266}
267
268
Note: See TracBrowser for help on using the repository browser.