Project

General

Profile

1 3118 perry
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000 Regents of the University of California and the
4
 *  National Center for Ecological Analysis and Synthesis
5
 *
6
 *  Author: Matthew Perry
7
 *  '$Date$'
8
 *  '$Revision$'
9
 *
10
 *  This program is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU General Public License
21
 *  along with this program; if not, write to the Free Software
22
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 *
24
 *  Purpose: Servlet to generate a styled layer descriptor (SLD)
25
 *           with a filter to restrict features on
26
 *           a WMS map to given docids
27
 *
28
 *  Status: Currently this is just a working stub
29
 *          with some hardcoded values. Since this needs to be
30
 *          fired off on every map redraw, we'll need a way to make
31
 *          the generation of docid list very efficient.
32
 *
33
 *  Usage: Append the URL as an "SLD" to any WMS GetMap request
34
 *    ex: http://server/context/wms?...&SLD=http://server/context/sldfactory?originalSld=data_points_style
35 3035 perry
 */
36 3118 perry
37
38 3035 perry
package edu.ucsb.nceas.metacat.spatial;
39
40
import edu.ucsb.nceas.utilities.XMLUtilities;
41 4080 daigle
import edu.ucsb.nceas.metacat.util.SystemUtil;
42 3035 perry
43
import javax.servlet.ServletConfig;
44
import javax.servlet.ServletContext;
45
import javax.servlet.ServletException;
46
import javax.servlet.ServletInputStream;
47
import javax.servlet.http.HttpServlet;
48
import javax.servlet.http.HttpServletRequest;
49
import javax.servlet.http.HttpServletResponse;
50
import javax.servlet.http.HttpSession;
51
import javax.servlet.http.HttpUtils;
52
import javax.servlet.ServletOutputStream;
53
54
import javax.xml.parsers.DocumentBuilder;
55
import javax.xml.parsers.DocumentBuilderFactory;
56
import javax.xml.parsers.FactoryConfigurationError;
57
import javax.xml.parsers.ParserConfigurationException;
58
59
import org.xml.sax.SAXException;
60
import org.xml.sax.SAXParseException;
61
62
import java.io.File;
63
import java.io.IOException;
64 3118 perry
import java.io.FileNotFoundException;
65 3035 perry
66 3118 perry
import java.util.Vector;
67
68 3035 perry
import org.w3c.dom.*;
69
70 3040 perry
/**
71
 * Class to generate Styled Layer Descriptors allowing geoserver to
72
 * filter the feature rendering based on various contraints
73
 * such as permissions, non-spatial queries and skin configuration.
74
 */
75 3035 perry
public class SldFactory extends HttpServlet {
76
77
  static Document document;
78
  static String sld;
79
80 3040 perry
  /**
81
   * Handle "GET" method requests from HTTP clients
82
   *
83
   * @param request Incoming servlet request.
84
   * @param response Servlet response.
85
   */
86 3035 perry
  public void doGet(HttpServletRequest request, HttpServletResponse response)
87
  throws ServletException, IOException
88
  {
89
    handleGetOrPost(request, response);
90
  }
91
92 3040 perry
  /**
93
   * Handle "POST" method requests from HTTP clients
94
   *
95
   * @param request Incoming servlet request.
96
   * @param response Servlet response.
97
   */
98 3035 perry
  public void doPost(HttpServletRequest request, HttpServletResponse response)
99
  throws ServletException, IOException
100
  {
101
    handleGetOrPost(request, response);
102
  }
103
104
  /**
105 4080 daigle
	 * Control servlet response depending on the action parameter specified
106
	 * Modifies the original SLD according to various access contraints and
107
	 * sends it as the servlet response.
108
	 *
109
	 * @param request
110
	 *            Incoming servlet request.
111
	 * @param response
112
	 *            Servlet response.
113
	 */
114
	private void handleGetOrPost(HttpServletRequest request, HttpServletResponse response)
115
			throws ServletException, IOException {
116
		String dataset = request.getParameter("originalSld");
117
118
		try {
119
			String certPath = SystemUtil.getContextDir();
120 4167 leinfelder
			String filename = certPath + "/data/styles/" + dataset;
121 4080 daigle
			String sld = getSld(filename);
122
			System.out.println(sld);
123
			response.setContentType("text/xml");
124
			response.getWriter().write(sld);
125
		} catch (FileNotFoundException fnf) {
126
			fnf.printStackTrace();
127
		} catch (Exception e) {
128
			e.printStackTrace();
129
		}
130
131
	}
132 3035 perry
133
  /**
134 4080 daigle
	 * Given a filename of an existing SLD document, reads the sld and adds an
135
	 * ogc:Filter to exclude/include certain docids based on user's permissions.
136
	 * The sld file is specified without path and must exist within geoserver's
137
	 * styles folder (context/data/styles/*)
138
	 *
139
	 * returns SLD document as a String.
140
	 *
141
	 * @param filename
142
	 *            Filename of the base sld.
143
	 * @todo Implement the doc id list queries for contraints.
144
	 */
145 3118 perry
  private String getSld(String filename) throws FileNotFoundException
146 3035 perry
  {
147
	    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
148 3118 perry
	    Vector allowedDocids = new Vector();
149 3035 perry
150 3118 perry
	    /*
151
	     * TODO :
152
	     *  Get the list of allowable docids due to
153
	     *    access contraints (based on current logged-in user)
154
	     *    skin filtering (eg organization name)
155
	     *    existing non-spatial query (eg taxonomic query)
156
	     *
157
	     *  These could ideally be cached as session variables to improve
158
	     *  speed over running expensive SQL queries on
159
	     *  each map redraw.
160
	     *
161
	     * Combined, these will be a vector of allowed docids that
162
	     * are to be displayed on the map
163
	     *
164
	     * Below is just a hardcoded example of the above...
165
	     *
166
	     */
167
	    allowedDocids.add("nceas.288");
168
	    allowedDocids.add("nrs.720");
169
170
	    String rulesString = "";
171
172 3035 perry
	    try {
173 3118 perry
		    DocumentBuilder builder = factory.newDocumentBuilder();
174
		    document = builder.parse( new File(filename) );
175
		    Element root = document.getDocumentElement();
176
177
		    NodeList elemList = document.getElementsByTagName("Rule");
178
		    Node ruleNode = elemList.item(0);
179
180
		    // Get the Element/node comprising the ogc:Filter for all of the above
181
		    Element filterElement = getFilterElement(document,allowedDocids);
182
183
		    // Append the Filter to the ruleNode
184
		    ruleNode.appendChild(filterElement);
185
186
		    // Write new DOM as a string
187
		    rulesString = XMLUtilities.getDOMTreeAsString((Node) root, true);
188
189 3035 perry
	    } catch (SAXException sxe) {
190
	       sxe.printStackTrace();
191
	    } catch (ParserConfigurationException pce) {
192
	       pce.printStackTrace();
193
	    } catch (IOException ioe) {
194
	       ioe.printStackTrace();
195 3118 perry
	    }
196 3035 perry
	    return rulesString;
197
  }
198
199
  /**
200
   * Given a DOM document and a vector of docids,
201
   * Creates an OGC Filter node
202
   *
203
   * @param inDoc	DOM document.
204 3118 perry
   * @param docids 	Vector of documents allowed in the map.
205 3035 perry
   */
206 3118 perry
  private Element getFilterElement(Document inDoc, Vector docids)
207 3035 perry
  {
208
	  Element filterElem = inDoc.createElement("ogc:Filter");
209 3118 perry
	  Element orElem = inDoc.createElement("ogc:Or");
210
	  String docid = "";
211 3035 perry
212 3118 perry
	  // Begin loop thru vector of allowed docids
213
	  for (int i = 0; i < docids.size(); i++) {
214
		  Element opElem = inDoc.createElement("ogc:PropertyIsEqualTo");
215
216
		  Element propertyElem = inDoc.createElement("ogc:PropertyName");
217
		  Text propertyText = inDoc.createTextNode("docid");
218
		  propertyElem.appendChild(propertyText);
219
220
		  Element literalElem = inDoc.createElement("ogc:Literal");
221
222
		  docid = (String)docids.elementAt(i);
223
		  Text literalText = inDoc.createTextNode(docid);
224
		  literalElem.appendChild(literalText);
225
226
		  opElem.appendChild(propertyElem);
227
		  opElem.appendChild(literalElem);
228
229
		  orElem.appendChild(opElem);
230
		  // END LOOP
231
	  }
232 3035 perry
233 3118 perry
	  filterElem.appendChild(orElem);
234 3035 perry
	  return filterElem;
235
  }
236
237
}