1 |
|
/*
|
2 |
|
* Styled Layer Descriptor Factory
|
3 |
|
* Author: Matt Perry
|
4 |
|
* Status: testing
|
5 |
|
* MPTODO: Use a spatial access constraints class to generate the appropriate SLD filter
|
|
1 |
/**
|
|
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
|
6 |
35 |
*/
|
|
36 |
|
|
37 |
|
7 |
38 |
package edu.ucsb.nceas.metacat.spatial;
|
8 |
39 |
|
9 |
40 |
import edu.ucsb.nceas.utilities.XMLUtilities;
|
|
41 |
import edu.ucsb.nceas.metacat.MetaCatUtil;
|
10 |
42 |
|
11 |
43 |
import javax.servlet.ServletConfig;
|
12 |
44 |
import javax.servlet.ServletContext;
|
... | ... | |
29 |
61 |
|
30 |
62 |
import java.io.File;
|
31 |
63 |
import java.io.IOException;
|
|
64 |
import java.io.FileNotFoundException;
|
32 |
65 |
|
|
66 |
import java.util.Vector;
|
|
67 |
|
33 |
68 |
import org.w3c.dom.*;
|
34 |
69 |
|
35 |
70 |
/**
|
... | ... | |
73 |
108 |
*
|
74 |
109 |
* @param request Incoming servlet request.
|
75 |
110 |
* @param response Servlet response.
|
76 |
|
* @todo Determine filename from variables in metacat.properties.
|
77 |
111 |
*/
|
78 |
112 |
private void handleGetOrPost(HttpServletRequest request, HttpServletResponse response)
|
79 |
113 |
throws ServletException, IOException
|
80 |
114 |
{
|
81 |
|
//String dataset = request.getParameter("dataset");
|
82 |
|
// MPTODO : Eventually use dataset to determine filename
|
83 |
|
String filename = "/var/lib/tomcat5/webapps/knb/style/skins/ebm/spatial/data_bounds_style.sld";
|
84 |
|
String sld = getSld(filename);
|
|
115 |
String dataset = request.getParameter("originalSld");
|
|
116 |
String filename = MetaCatUtil.getOption("certPath") + "data/styles/" + dataset;
|
|
117 |
try {
|
|
118 |
String sld = getSld(filename);
|
|
119 |
System.out.println(sld);
|
|
120 |
response.setContentType("text/xml");
|
|
121 |
response.getWriter().write(sld);
|
|
122 |
} catch (FileNotFoundException fnf) {
|
|
123 |
fnf.printStackTrace();
|
|
124 |
} catch (Exception e) {
|
|
125 |
e.printStackTrace();
|
|
126 |
}
|
85 |
127 |
|
86 |
|
response.setContentType("text/xml");
|
87 |
|
response.getWriter().write(sld);
|
88 |
|
|
89 |
|
System.out.println("\n*** SldFactory request handled ***\n");
|
90 |
128 |
}
|
91 |
129 |
|
92 |
130 |
/**
|
93 |
131 |
* Given a filename of an existing SLD document,
|
94 |
132 |
* reads the sld and adds an ogc:Filter to exclude/include
|
95 |
133 |
* certain docids based on user's permissions.
|
|
134 |
* The sld file is specified without path and
|
|
135 |
* must exist within geoserver's styles folder (context/data/styles/*)
|
96 |
136 |
*
|
97 |
137 |
* returns SLD document as a String.
|
98 |
138 |
*
|
99 |
139 |
* @param filename Filename of the base sld.
|
100 |
140 |
* @todo Implement the doc id list queries for contraints.
|
101 |
141 |
*/
|
102 |
|
private String getSld(String filename)
|
|
142 |
private String getSld(String filename) throws FileNotFoundException
|
103 |
143 |
{
|
104 |
144 |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
|
145 |
Vector allowedDocids = new Vector();
|
105 |
146 |
|
|
147 |
/*
|
|
148 |
* TODO :
|
|
149 |
* Get the list of allowable docids due to
|
|
150 |
* access contraints (based on current logged-in user)
|
|
151 |
* skin filtering (eg organization name)
|
|
152 |
* existing non-spatial query (eg taxonomic query)
|
|
153 |
*
|
|
154 |
* These could ideally be cached as session variables to improve
|
|
155 |
* speed over running expensive SQL queries on
|
|
156 |
* each map redraw.
|
|
157 |
*
|
|
158 |
* Combined, these will be a vector of allowed docids that
|
|
159 |
* are to be displayed on the map
|
|
160 |
*
|
|
161 |
* Below is just a hardcoded example of the above...
|
|
162 |
*
|
|
163 |
*/
|
|
164 |
allowedDocids.add("nceas.288");
|
|
165 |
allowedDocids.add("nrs.720");
|
|
166 |
|
|
167 |
String rulesString = "";
|
|
168 |
|
106 |
169 |
try {
|
107 |
|
DocumentBuilder builder = factory.newDocumentBuilder();
|
108 |
|
document = builder.parse( new File(filename) );
|
|
170 |
DocumentBuilder builder = factory.newDocumentBuilder();
|
|
171 |
document = builder.parse( new File(filename) );
|
|
172 |
Element root = document.getDocumentElement();
|
|
173 |
|
|
174 |
NodeList elemList = document.getElementsByTagName("Rule");
|
|
175 |
Node ruleNode = elemList.item(0);
|
|
176 |
|
|
177 |
// Get the Element/node comprising the ogc:Filter for all of the above
|
|
178 |
Element filterElement = getFilterElement(document,allowedDocids);
|
|
179 |
|
|
180 |
// Append the Filter to the ruleNode
|
|
181 |
ruleNode.appendChild(filterElement);
|
|
182 |
|
|
183 |
// Write new DOM as a string
|
|
184 |
rulesString = XMLUtilities.getDOMTreeAsString((Node) root, true);
|
|
185 |
|
109 |
186 |
} catch (SAXException sxe) {
|
110 |
187 |
sxe.printStackTrace();
|
111 |
188 |
} catch (ParserConfigurationException pce) {
|
112 |
189 |
pce.printStackTrace();
|
113 |
190 |
} catch (IOException ioe) {
|
114 |
191 |
ioe.printStackTrace();
|
115 |
|
}
|
116 |
|
|
117 |
|
Element root = document.getDocumentElement();
|
118 |
|
NodeList elemList = document.getElementsByTagName("Rule");
|
119 |
|
Node ruleNode = elemList.item(0);
|
120 |
|
|
121 |
|
// Get the list of docids due to access contrainsts
|
122 |
|
|
123 |
|
// Get the list of docids due to skin filtering of org names
|
124 |
|
|
125 |
|
// Get the list of docids due to existing query (eg taxonomic)
|
126 |
|
|
127 |
|
// Get the Element/node comprising the ogc:Filter for all of the above
|
128 |
|
Element filterElement = getFilterElement(document);
|
129 |
|
|
130 |
|
// Append the Filter to the ruleNode
|
131 |
|
ruleNode.appendChild(filterElement);
|
132 |
|
|
133 |
|
// Write new DOM as a string
|
134 |
|
String rulesString = XMLUtilities.getDOMTreeAsString((Node) root, true);
|
135 |
|
|
|
192 |
}
|
136 |
193 |
return rulesString;
|
137 |
194 |
}
|
138 |
195 |
|
... | ... | |
141 |
198 |
* Creates an OGC Filter node
|
142 |
199 |
*
|
143 |
200 |
* @param inDoc DOM document.
|
144 |
|
*
|
|
201 |
* @param docids Vector of documents allowed in the map.
|
145 |
202 |
*/
|
146 |
|
private Element getFilterElement(Document inDoc)
|
|
203 |
private Element getFilterElement(Document inDoc, Vector docids)
|
147 |
204 |
{
|
148 |
205 |
Element filterElem = inDoc.createElement("ogc:Filter");
|
|
206 |
Element orElem = inDoc.createElement("ogc:Or");
|
|
207 |
String docid = "";
|
149 |
208 |
|
150 |
|
// MPTODO : BEGIN LOOP thru vector of docids
|
151 |
|
Element opElem = inDoc.createElement("ogc:PropertyIsEqualTo");
|
|
209 |
// Begin loop thru vector of allowed docids
|
|
210 |
for (int i = 0; i < docids.size(); i++) {
|
|
211 |
Element opElem = inDoc.createElement("ogc:PropertyIsEqualTo");
|
|
212 |
|
|
213 |
Element propertyElem = inDoc.createElement("ogc:PropertyName");
|
|
214 |
Text propertyText = inDoc.createTextNode("docid");
|
|
215 |
propertyElem.appendChild(propertyText);
|
|
216 |
|
|
217 |
Element literalElem = inDoc.createElement("ogc:Literal");
|
|
218 |
|
|
219 |
docid = (String)docids.elementAt(i);
|
|
220 |
Text literalText = inDoc.createTextNode(docid);
|
|
221 |
literalElem.appendChild(literalText);
|
|
222 |
|
|
223 |
opElem.appendChild(propertyElem);
|
|
224 |
opElem.appendChild(literalElem);
|
|
225 |
|
|
226 |
orElem.appendChild(opElem);
|
|
227 |
// END LOOP
|
|
228 |
}
|
152 |
229 |
|
153 |
|
Element propertyElem = inDoc.createElement("ogc:PropertyName");
|
154 |
|
Text propertyText = inDoc.createTextNode("docid");
|
155 |
|
propertyElem.appendChild(propertyText);
|
156 |
|
|
157 |
|
Element literalElem = inDoc.createElement("ogc:Literal");
|
158 |
|
Text literalText = inDoc.createTextNode("perry.1"); // i
|
159 |
|
literalElem.appendChild(literalText);
|
160 |
|
|
161 |
|
opElem.appendChild(propertyElem);
|
162 |
|
opElem.appendChild(literalElem);
|
163 |
|
filterElem.appendChild(opElem);
|
164 |
|
// END LOOP
|
165 |
|
|
|
230 |
filterElem.appendChild(orElem);
|
166 |
231 |
return filterElem;
|
167 |
232 |
}
|
168 |
233 |
|
Initial architecture for dynamically generating SLD/OGC:Filter documents to control which docids get shown on the map. The sldfactory servlet is in place to handle this but is not fully functional since there is currently no way to quickly and dynamically generate a list of allowable docids with a level of performance acceptable for real-time web mapping.