001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.vfny.geoserver.form.data;
006:
007: import org.apache.struts.action.ActionError;
008: import org.apache.struts.action.ActionErrors;
009: import org.apache.struts.action.ActionForm;
010: import org.apache.struts.action.ActionMapping;
011: import org.geotools.data.DataStoreFactorySpi;
012: import org.geotools.data.DataStoreFactorySpi.Param;
013: import org.vfny.geoserver.config.DataConfig;
014: import org.vfny.geoserver.config.DataStoreConfig;
015: import org.vfny.geoserver.global.GeoserverDataDirectory;
016: import org.vfny.geoserver.global.UserContainer;
017: import org.vfny.geoserver.util.DataStoreUtils;
018: import org.vfny.geoserver.util.Requests;
019: import java.io.File;
020: import java.io.IOException;
021: import java.net.MalformedURLException;
022: import java.net.URL;
023: import java.util.ArrayList;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028: import java.util.SortedSet;
029: import java.util.TreeSet;
030: import javax.servlet.ServletContext;
031: import javax.servlet.http.HttpServletRequest;
032:
033: /**
034: * Represents the information required for editing a DataStore.
035: *
036: * <p>
037: * The parameters required by a DataStore are dynamically generated from the
038: * DataStoreFactorySPI. Most use of DataStoreFactorySPI has been hidden behind
039: * the DataStoreUtil class.
040: * </p>
041: *
042: * @author Richard Gould, Refractions Research
043: */
044: public class DataDataStoresEditorForm extends ActionForm {
045: /** Help text for Params if available */
046: private ArrayList paramHelp;
047:
048: /**
049: * Used to identify the DataStore being edited. Maybe we should grab this
050: * from session?
051: */
052: private String dataStoreId;
053:
054: /** Enabled status of DataStore */
055: private boolean enabled;
056:
057: /* NamespaceID used for DataStore content */
058: private String namespaceId;
059:
060: /* Description of DataStore (abstract?) */
061: private String description;
062:
063: // These are not stored in a single map so we can access them
064: // easily from JSP page
065: //
066:
067: /** String representation of connection parameter keys */
068: private List paramKeys;
069:
070: /** String representation of connection parameter values */
071: private List paramValues;
072:
073: /** String representation of connection paramter types */
074: private List paramTypes;
075:
076: /** String representation of paramters which are required */
077: private List paramRequired;
078:
079: //
080: // More hacky attempts to transfer information into the JSP smoothly
081: //
082:
083: /** Available NamespaceIds */
084: private SortedSet namespaces;
085:
086: /**
087: * Because of the way that STRUTS works, if the user does not check the
088: * enabled box, or unchecks it, setEnabled() is never called, thus we must
089: * monitor setEnabled() to see if it doesn't get called. This must be
090: * accessible, as ActionForms need to know about it -- there is no way we
091: * can tell whether we are about to be passed to an ActionForm or not.
092: * Probably a better way to do this, but I can't think of one. -rgould
093: */
094: private boolean enabledChecked = false;
095:
096: public void reset(ActionMapping mapping, HttpServletRequest request) {
097: super .reset(mapping, request);
098:
099: enabledChecked = false;
100:
101: ServletContext context = getServlet().getServletContext();
102: DataConfig config = (DataConfig) context
103: .getAttribute(DataConfig.CONFIG_KEY);
104:
105: namespaces = new TreeSet(config.getNameSpaces().keySet());
106:
107: DataStoreConfig dsConfig = Requests.getUserContainer(request)
108: .getDataStoreConfig();
109:
110: if (dsConfig == null) {
111: // something is horribly wrong no DataStoreID selected!
112: // The JSP needs to not include us if there is no
113: // selected DataStore
114: //
115: throw new RuntimeException(
116: "selectedDataStoreId required in Session");
117: }
118:
119: dataStoreId = dsConfig.getId();
120: description = dsConfig.getAbstract();
121: enabled = dsConfig.isEnabled();
122: namespaceId = dsConfig.getNameSpaceId();
123:
124: if (namespaceId.equals("")) {
125: namespaceId = config.getDefaultNameSpace().getPrefix();
126: }
127:
128: //Retrieve connection params
129: DataStoreFactorySpi factory = dsConfig.getFactory();
130: Param[] params = factory.getParametersInfo();
131:
132: paramKeys = new ArrayList(params.length);
133: paramValues = new ArrayList(params.length);
134: paramTypes = new ArrayList(params.length);
135: paramHelp = new ArrayList(params.length);
136: paramRequired = new ArrayList(params.length);
137:
138: for (int i = 0; i < params.length; i++) {
139: Param param = params[i];
140: String key = param.key;
141:
142: if ("namespace".equals(key)) {
143: // skip namespace as it is *magic* and
144: // appears to be an entry used in all datastores?
145: //
146: continue;
147: }
148:
149: Object value = dsConfig.getConnectionParams().get(key);
150: String text;
151:
152: if (value == null) {
153: text = null;
154: } else if (value instanceof String) {
155: text = (String) value;
156: } else {
157: text = param.text(value);
158: }
159:
160: paramKeys.add(key);
161: paramValues.add((text != null) ? text : "");
162: paramTypes.add(param.type.getName());
163: paramHelp.add(param.description
164: + (param.required ? "" : " (optional)"));
165: paramRequired.add(Boolean.valueOf(param.required)
166: .toString());
167: }
168: }
169:
170: public ActionErrors validate(ActionMapping mapping,
171: HttpServletRequest request) {
172: ActionErrors errors = new ActionErrors();
173:
174: // Selected DataStoreConfig is in session
175: //
176: UserContainer user = Requests.getUserContainer(request);
177: DataStoreConfig dsConfig = user.getDataStoreConfig();
178:
179: //
180: // dsConfig is the only way to get a factory
181: DataStoreFactorySpi factory = dsConfig.getFactory();
182: Param[] info = factory.getParametersInfo();
183:
184: Map connectionParams = new HashMap();
185:
186: // Convert Params into the kind of Map we actually need
187: //
188: for (int i = 0; i < paramKeys.size(); i++) {
189: String key = (String) getParamKey(i);
190:
191: Param param = DataStoreUtils.find(info, key);
192:
193: if (param == null) {
194: errors.add("paramValue[" + i + "]", new ActionError(
195: "error.dataStoreEditor.param.missing", key,
196: factory.getDescription()));
197:
198: continue;
199: }
200:
201: //special case check for url
202: if (URL.class.equals(param.type)) {
203: String value = getParamValue(i);
204:
205: if ((value != null) && !"".equals(value)) {
206: URL url = null;
207:
208: try {
209: // if this does not throw an exception then cool
210: url = new URL(value);
211: } catch (MalformedURLException e) {
212: //check for special case of file
213: try {
214: if (GeoserverDataDirectory.findDataFile(
215: value).exists()) {
216: url = new URL("file://" + value);
217: setParamValues(i, "file://" + value);
218: }
219: } catch (MalformedURLException e1) {
220: //let this paramter die later
221: }
222: }
223:
224: if (url != null
225: && (url.getProtocol() == null || url
226: .getProtocol().equals("file"))) {
227: //do a check to see if the shapefile url is valid, report
228: // an error if it does not
229: File file = GeoserverDataDirectory
230: .findDataFile(value);
231: FormUtils.checkFileExistsAndCanRead(file,
232: errors);
233: }
234: }
235: }
236:
237: Object value;
238:
239: try {
240: value = param.lookUp(getParams());
241:
242: if (value instanceof String) {
243: value = param.parse((String) value);
244: }
245: } catch (IOException erp) {
246: errors.add("paramValue[" + i + "]", new ActionError(
247: "error.dataStoreEditor.param.parse", key,
248: param.type, erp));
249:
250: continue;
251: } catch (Throwable t) { //thrown by param.parse()
252: errors.add("paramValue[" + i + "]", new ActionError(
253: "error.dataStoreEditor.param.parse", key,
254: param.type, t));
255:
256: continue;
257: }
258:
259: if ((value == null) && param.required) {
260: errors.add("paramValue[" + i + "]", new ActionError(
261: "error.dataStoreEditor.param.required", key));
262:
263: continue;
264: }
265:
266: if (value != null) {
267: connectionParams.put(key, value);
268: }
269: }
270:
271: // put magic namespace into the mix
272: //
273: //connectionParams.put("namespace", getNamespaceId());
274: dump("form", connectionParams);
275:
276: // Factory will provide even more stringent checking
277: //
278: if (!factory.canProcess(connectionParams)) {
279: errors.add("paramValue", new ActionError(
280: "error.datastoreEditor.validation"));
281: }
282:
283: return errors;
284: }
285:
286: /** Used to debug connection parameters */
287: public void dump(String msg, Map params) {
288: if (msg != null) {
289: System.out.print(msg + " ");
290: }
291:
292: System.out.print(" connection params { ");
293:
294: for (Iterator i = params.entrySet().iterator(); i.hasNext();) {
295: Map.Entry entry = (Map.Entry) i.next();
296: System.out.print(entry.getKey());
297: System.out.print("=");
298:
299: if (entry.getValue() == null) {
300: System.out.print("null");
301: } else if (entry.getValue() instanceof String) {
302: System.out.print("\"");
303: System.out.print(entry.getValue());
304: System.out.print("\"");
305: } else {
306: System.out.print(entry.getValue());
307: }
308:
309: if (i.hasNext()) {
310: System.out.print(", ");
311: }
312: }
313:
314: System.out.println("}");
315: }
316:
317: public Map getParams() {
318: Map map = new HashMap();
319:
320: for (int i = 0; i < paramKeys.size(); i++) {
321: map.put(paramKeys.get(i), paramValues.get(i));
322: }
323:
324: return map;
325: }
326:
327: /**
328: * DOCUMENT ME!
329: *
330: * @return
331: */
332: public List getParamKeys() {
333: return paramKeys;
334: }
335:
336: /**
337: * DOCUMENT ME!
338: *
339: * @param index DOCUMENT ME!
340: *
341: * @return
342: */
343: public String getParamKey(int index) {
344: return (String) paramKeys.get(index);
345: }
346:
347: /**
348: * DOCUMENT ME!
349: *
350: * @param index DOCUMENT ME!
351: *
352: * @return
353: */
354: public String getParamValue(int index) {
355: return (String) paramValues.get(index);
356: }
357:
358: /**
359: * DOCUMENT ME!
360: *
361: * @param index
362: * @param value DOCUMENT ME!
363: */
364: public void setParamValues(int index, String value) {
365: paramValues.set(index, value);
366: }
367:
368: /**
369: * getDataStoreId purpose.
370: *
371: * <p>
372: * Description ...
373: * </p>
374: *
375: * @return
376: */
377: public String getDataStoreId() {
378: return dataStoreId;
379: }
380:
381: /**
382: * getDescription purpose.
383: *
384: * <p>
385: * Description ...
386: * </p>
387: *
388: * @return
389: */
390: public String getDescription() {
391: return description;
392: }
393:
394: /**
395: * isEnabled purpose.
396: *
397: * <p>
398: * Description ...
399: * </p>
400: *
401: * @return
402: */
403: public boolean isEnabled() {
404: return enabled;
405: }
406:
407: /**
408: * getNamespaces purpose.
409: *
410: * <p>
411: * Description ...
412: * </p>
413: *
414: * @return
415: */
416: public SortedSet getNamespaces() {
417: return namespaces;
418: }
419:
420: /**
421: * getParamValues purpose.
422: *
423: * <p>
424: * Description ...
425: * </p>
426: *
427: * @return
428: */
429: public List getParamValues() {
430: return paramValues;
431: }
432:
433: /**
434: * setDescription purpose.
435: *
436: * <p>
437: * Description ...
438: * </p>
439: *
440: * @param string
441: */
442: public void setDescription(String string) {
443: description = string;
444: }
445:
446: /**
447: * setEnabled purpose.
448: *
449: * <p>
450: * Description ...
451: * </p>
452: *
453: * @param b
454: */
455: public void setEnabled(boolean b) {
456: setEnabledChecked(true);
457: enabled = b;
458: }
459:
460: /**
461: * setParamKeys purpose.
462: *
463: * <p>
464: * Description ...
465: * </p>
466: *
467: * @param list
468: */
469: public void setParamKeys(List list) {
470: paramKeys = list;
471: }
472:
473: /**
474: * setParamValues purpose.
475: *
476: * <p>
477: * Description ...
478: * </p>
479: *
480: * @param list
481: */
482: public void setParamValues(List list) {
483: paramValues = list;
484: }
485:
486: /**
487: * getNamespaceId purpose.
488: *
489: * <p>
490: * Description ...
491: * </p>
492: *
493: * @return
494: */
495: public String getNamespaceId() {
496: return namespaceId;
497: }
498:
499: /**
500: * setNamespaceId purpose.
501: *
502: * <p>
503: * Description ...
504: * </p>
505: *
506: * @param string
507: */
508: public void setNamespaceId(String string) {
509: namespaceId = string;
510: }
511:
512: /**
513: * enabledChecked property
514: *
515: * @return DOCUMENT ME!
516: */
517: public boolean isEnabledChecked() {
518: return enabledChecked;
519: }
520:
521: /**
522: * enabledChecked property
523: *
524: * @param b DOCUMENT ME!
525: */
526: public void setEnabledChecked(boolean b) {
527: enabledChecked = b;
528: }
529:
530: /**
531: * Index property paramHelp
532: *
533: * @return DOCUMENT ME!
534: */
535: public String[] getParamHelp() {
536: return (String[]) paramHelp
537: .toArray(new String[paramHelp.size()]);
538: }
539:
540: /**
541: * Index property paramHelp
542: *
543: * @param index DOCUMENT ME!
544: *
545: * @return DOCUMENT ME!
546: */
547: public String getParamHelp(int index) {
548: return (String) paramHelp.get(index);
549: }
550:
551: /**
552: * @return list containing the name of the class of each paramter.
553: */
554: public List getParamTypes() {
555: return paramTypes;
556: }
557:
558: /**
559: * @param index paramter index.
560: *
561: * @return The string represention of the class of the paramter at the
562: * specified index.
563: */
564: public String getParamType(int index) {
565: return (String) paramTypes.get(index);
566: }
567:
568: /**
569: * @return list containing java.lang.Boolean values representing which
570: * paramters are required.
571: */
572: public List getParamRequired() {
573: return paramRequired;
574: }
575:
576: /**
577: * @param index paramter index.
578: * @return True if the paramter is required, otherwise false.
579: */
580: public String getParamRequired(int index) {
581: return (String) paramRequired.get(index);
582: }
583: }
|