source: gs3-extensions/iiif-servlet/trunk/src/gsdl-src/java/org/greenstone/gsdl3/IIIFServerBridge.java

Last change on this file was 36996, checked in by davidb, 17 months ago

Changes in response to testing out the retrieval of a document sub-section image

File size: 10.4 KB
Line 
1/*
2 * IIIFServerBridge.java
3 * Copyright (C) 2018 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;
20
21import java.io.IOException;
22import java.io.PrintWriter;
23import java.util.HashSet;
24import java.util.Iterator;
25import java.util.Map;
26
27import javax.servlet.ServletConfig;
28import javax.servlet.ServletException;
29import javax.servlet.UnavailableException;
30import javax.servlet.http.HttpServletRequest;
31import javax.servlet.http.HttpServletResponse;
32
33import org.apache.log4j.Logger;
34import org.greenstone.gsdl3.comms.Communicator;
35import org.greenstone.gsdl3.comms.SOAPCommunicator;
36import org.greenstone.gsdl3.core.IIIFMessageRouter;
37import org.greenstone.gsdl3.core.IIIFReceptionist;
38import org.greenstone.gsdl3.util.GSConstants;
39import org.greenstone.gsdl3.util.GSParams;
40import org.greenstone.gsdl3.util.GSXML;
41import org.greenstone.gsdl3.util.IIIFXML;
42import org.greenstone.gsdl3.util.XMLConverter;
43import org.w3c.dom.Document;
44import org.w3c.dom.Element;
45import org.w3c.dom.Node;
46
47
48
49import java.io.StringWriter;
50
51//import javax.xml.parsers.DocumentBuilder;
52//import javax.xml.parsers.DocumentBuilderFactory;
53import javax.xml.transform.OutputKeys;
54import javax.xml.transform.Transformer;
55import javax.xml.transform.TransformerException;
56import javax.xml.transform.TransformerFactory;
57import javax.xml.transform.dom.DOMSource;
58import javax.xml.transform.stream.StreamResult;
59
60
61/** a class the serve as a bridge between the Cantaloupe IIIF image server and
62 * Greenstone collections. Loosely based on OAIServer
63 *
64 * the init method is called only once - the first time the bridge is established
65 * then doGet() each time a document image request is made
66 * @see Receptionist
67 */
68/**
69 * IIIF server configuration instructions *
70 *
71 */
72public class IIIFServerBridge
73{
74 /** the receptionist to send messages to */
75 protected IIIFReceptionist recept = null;
76
77 /**
78 * The name of the site with which we will finally be dealing, whether it is
79 * a local site or a remote site through a communicator.
80 */
81 protected String site = "";
82
83 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.IIIFServerBridge.class.getName());
84
85 private void configure() throws UnavailableException
86 {
87 // Read in IIIFConfig.xml (residing web/WEB-INF/classes/) and
88 //use it to configure the receptionist.
89 Element iiif_config = IIIFXML.getIIIFConfigXML();
90 if (iiif_config == null)
91 {
92 logger.error("Fail to parse IIIF config file IIIFConfig.xml.");
93 throw new UnavailableException("IIIFServerBridge: Couldn't parse IIIFConfig.xml");
94 }
95 // pass it to the receptionist
96 if (!this.recept.configure(iiif_config)) {
97 logger.error("Couldn't configure IIIF receptionist");
98 throw new UnavailableException("IIIFServerBridge: Couldn't configure receptionist");
99 }
100 }
101
102 /**
103 * initialise the class
104 */
105 public void init(String site_name) throws UnavailableException, Exception
106 {
107 org.greenstone.util.GlobalProperties.loadGlobalProperties("");
108 java.io.InputStream in = Class.forName("org.greenstone.util.GlobalProperties").getClassLoader().getResourceAsStream("global.properties");
109
110 String tomcat_context = System.getProperty("tomcat.context");
111
112 // the receptionist -the servlet will talk to this
113 this.recept = new IIIFReceptionist();
114
115 //this site_name could consist of comma separated more than one site name.
116 IIIFMessageRouter message_router = new IIIFMessageRouter();
117
118 message_router.setSiteName(site_name);
119 // lots of work is done in this step; see IIIFMessageRouter.java
120 if (!message_router.configure()) {
121 throw new UnavailableException("IIIFServerBridge: Couldn't configure IIIFMessageRouter");
122 }
123 this.recept.setSiteName(site_name);
124 this.recept.setMessageRouter(message_router);
125
126 configure();
127 } // end of init()
128
129 /*
130 Written but never used/tested
131 */
132
133 public void remote_init(String remote_site_name, String remote_site_type, String remote_site_address) throws UnavailableException
134 {
135 if (remote_site_name == null || remote_site_type == null || remote_site_address == null)
136 {
137 logger.error("Initialisation paramters not all set!");
138 logger.error("You must have remote_site_name, remote_site_type and remote_site_address set");
139 throw new UnavailableException("IIIFServerBridge: incorrect remote connection parameters specified");
140 }
141
142 // the receptionist -the servlet will talk to this
143 this.recept = new IIIFReceptionist();
144
145 // talking to a remote site, create a communicator
146 Communicator communicator = null;
147 // we need to create the XML to configure the communicator
148 Document site_doc = XMLConverter.newDOM();
149 Element site_elem = site_doc.createElement(GSXML.SITE_ELEM);
150 site_elem.setAttribute(GSXML.TYPE_ATT, remote_site_type);
151 site_elem.setAttribute(GSXML.NAME_ATT, remote_site_name);
152 site_elem.setAttribute(GSXML.ADDRESS_ATT, remote_site_address);
153
154 if (remote_site_type.equals(GSXML.COMM_TYPE_SOAP_JAVA))
155 {
156 communicator = new SOAPCommunicator();
157 }
158 else
159 {
160 logger.error("IIIFServerBridge.init Error: invalid Communicator type: " + remote_site_type);
161 throw new UnavailableException("IIIFServerBridge: invalid communicator type");
162 }
163
164 if (!communicator.configure(site_elem))
165 {
166 logger.error("IIIFServerBridge.init Error: Couldn't configure communicator");
167 throw new UnavailableException("IIIFServerBridge: Couldn't configure communicator");
168 }
169 this.recept.setSiteName(remote_site_name);
170 this.recept.setMessageRouter(communicator);
171
172 configure();
173 } // end of remote_init()
174
175 // Based on:
176 // https://stackoverflow.com/questions/4412848/xml-node-to-string-in-java
177
178 private static String nodeToString(Node node) {
179 StringWriter sw = new StringWriter();
180 try {
181 Transformer t = TransformerFactory.newInstance().newTransformer();
182 t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
183 t.setOutputProperty(OutputKeys.INDENT, "yes");
184 t.transform(new DOMSource(node), new StreamResult(sw));
185 } catch (TransformerException te) {
186 System.out.println("nodeToString Transformer Exception");
187 }
188 return sw.toString();
189 }
190
191 public String doGetDocumentMessage(String identifier)
192 {
193 String result = "";
194
195 String[] pairs = new String[2];
196 pairs[0] = "verb=GetRecord";
197 pairs[1] = "identifier="+identifier;
198
199 String verb = "GetRecord";
200 Document response_doc = XMLConverter.newDOM();
201 //Element xml_response = IIIFXML.createBasicResponse(response_doc, verb, pairs);
202 //Element verb_elem = null;
203
204 // compose the request message to the receptionist
205 Document request_doc = XMLConverter.newDOM();
206 Element xml_message = request_doc.createElement(GSXML.MESSAGE_ELEM);
207 Element xml_request = request_doc.createElement(GSXML.REQUEST_ELEM);
208 xml_request.setAttribute(GSXML.TO_ATT, verb);
209 addParams(xml_request, pairs);
210
211 xml_message.appendChild(xml_request);
212
213 Node xml_result = this.recept.process(xml_message);
214 if (xml_result == null)
215 {
216 logger.error("xml_result is null");
217 //verb_elem = IIIFXML.createErrorElement(response_doc, "Internal error", "");
218 //xml_response.appendChild(verb_elem);
219 }
220 else
221 {
222 //logger.info("***** DEBUG: xml_result");
223 //logger.info(nodeToString(xml_result));
224
225 //
226 // All response elements are in the form (with a corresponding verb
227 // name): <message> <response> <verb> ... </verb> </response> </message>
228 //
229 Node res = GSXML.getChildByTagName(xml_result, GSXML.RESPONSE_ELEM);
230 if (res == null)
231 {
232 logger.error("response element in xml_result is null");
233 //verb_elem = IIIFXML.createErrorElement(response_doc, "Internal error", "");
234 }
235 else {
236 Element verb_elem = GSXML.getFirstElementChild(res); // GetRecord
237 Node record_node = GSXML.getFirstElementChild(verb_elem); // record
238 Element metadata_list_elem = (Element)GSXML.getChildByTagName(record_node,"metadata"); // metadata
239
240 Element assocfilepath_metadata_elem = (Element)GSXML.getChildByTagName(metadata_list_elem,"assocfilepath");
241
242 if (assocfilepath_metadata_elem == null) {
243 logger.error("Failed to find metadata 'assocfilepath' for Document " + identifier);
244 //verb_elem = IIIFXML.createErrorElement(response_doc, "Internal error", "");
245 }
246 else {
247 String assocfilepath_metadata_val = GSXML.getNodeText(assocfilepath_metadata_elem);
248
249 Element image_metadata_elem = (Element)GSXML.getChildByTagName(metadata_list_elem,"Image");
250 if (assocfilepath_metadata_elem == null) {
251 logger.error("Failed to find metadata 'Image' for Document " + identifier);
252 }
253 else {
254 String image_metadata_val = GSXML.getNodeText(image_metadata_elem);
255
256 result = assocfilepath_metadata_val + "/" + image_metadata_val;
257 }
258 }
259 }
260
261 //xml_response.appendChild(response_doc.importNode(verb_elem, true));
262 }
263 return result;
264 }
265
266 /** append parameter elements to the request sent to the receptionist */
267 public void addParams(Element request, String[] pairs)
268 {
269 Document doc = request.getOwnerDocument();
270 // no params apart from the verb
271 if (pairs == null || pairs.length < 2)
272 return;
273
274 /**
275 * the request xml is composed in the form: <request> <param name=.../>
276 * <param name=.../> </request> (No paramList element in between).
277 */
278 for (int i = 1; i < pairs.length; i++)
279 {
280 //the first pair in pairs is the verb=xxx
281 int index = pairs[i].indexOf("=");
282 if (index != -1)
283 { //just a double check
284 Element param = GSXML.createParameter(doc, pairs[i].substring(0, index), IIIFXML.iiifDecode(pairs[i].substring(index + 1)));
285 request.appendChild(param);
286 }
287 }
288 }
289
290
291 public void destroy()
292 {
293 recept.cleanUp();
294 }
295
296}
Note: See TracBrowser for help on using the repository browser.