0001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
0002: * This code is licensed under the GPL 2.0 license, availible at the root
0003: * application directory.
0004: */
0005: package org.vfny.geoserver.global.xml;
0006:
0007: import java.awt.Color;
0008: import java.awt.geom.AffineTransform;
0009: import java.io.File;
0010: import java.io.FileOutputStream;
0011: import java.io.IOException;
0012: import java.io.OutputStreamWriter;
0013: import java.io.UnsupportedEncodingException;
0014: import java.io.Writer;
0015: import java.net.URLEncoder;
0016: import java.util.ArrayList;
0017: import java.util.HashMap;
0018: import java.util.Iterator;
0019: import java.util.Map;
0020: import java.util.logging.Level;
0021: import java.util.logging.Logger;
0022:
0023: import javax.xml.transform.TransformerException;
0024:
0025: import org.geotools.filter.FilterTransformer;
0026: import org.geotools.geometry.GeneralEnvelope;
0027: import org.opengis.coverage.grid.GridGeometry;
0028: import org.opengis.referencing.operation.MathTransform;
0029: import org.opengis.util.InternationalString;
0030: import org.vfny.geoserver.global.ConfigurationException;
0031: import org.vfny.geoserver.global.CoverageDimension;
0032: import org.vfny.geoserver.global.MetaDataLink;
0033: import org.vfny.geoserver.global.dto.AttributeTypeInfoDTO;
0034: import org.vfny.geoserver.global.dto.ContactDTO;
0035: import org.vfny.geoserver.global.dto.CoverageInfoDTO;
0036: import org.vfny.geoserver.global.dto.CoverageStoreInfoDTO;
0037: import org.vfny.geoserver.global.dto.DataDTO;
0038: import org.vfny.geoserver.global.dto.DataStoreInfoDTO;
0039: import org.vfny.geoserver.global.dto.FeatureTypeInfoDTO;
0040: import org.vfny.geoserver.global.dto.GeoServerDTO;
0041: import org.vfny.geoserver.global.dto.NameSpaceInfoDTO;
0042: import org.vfny.geoserver.global.dto.ServiceDTO;
0043: import org.vfny.geoserver.global.dto.StyleDTO;
0044: import org.vfny.geoserver.global.dto.WCSDTO;
0045: import org.vfny.geoserver.global.dto.WFSDTO;
0046: import org.vfny.geoserver.global.dto.WMSDTO;
0047:
0048: import com.vividsolutions.jts.geom.Envelope;
0049:
0050: /**
0051: * XMLConfigWriter purpose.
0052: *
0053: * <p>
0054: * This class is intended to store a configuration to be written and complete
0055: * the output to XML.
0056: * </p>
0057: *
0058: * <p></p>
0059: *
0060: * @author dzwiers, Refractions Research, Inc.
0061: * @version $Id: XMLConfigWriter.java 8482 2008-02-29 04:59:42Z arneke $
0062: */
0063: public class XMLConfigWriter {
0064: /** Used internally to create log information to detect errors. */
0065: private static final Logger LOGGER = org.geotools.util.logging.Logging
0066: .getLogger("org.vfny.geoserver.global");
0067:
0068: /**
0069: * XMLConfigWriter constructor.
0070: *
0071: * <p>
0072: * Should never be called.
0073: * </p>
0074: */
0075: private XMLConfigWriter() {
0076: }
0077:
0078: public static void store(DataDTO data, File root)
0079: throws ConfigurationException {
0080: if (LOGGER.isLoggable(Level.FINE)) {
0081: LOGGER.fine("In method store DataDTO");
0082: }
0083:
0084: if (data == null) {
0085: throw new ConfigurationException(
0086: "DataDTO is null: cannot write.");
0087: }
0088:
0089: WriterUtils.initFile(root, true);
0090:
0091: // boolean inDataDir = GeoserverDataDirectory.isTrueDataDir();
0092:
0093: //We're just checking if it's actually a data_dir, not trying to
0094: //to do backwards compatibility. So if an old data_dir is made in
0095: //the old way, on save it'll come to the new way.
0096: File fileDir = root; // ? root : new File(root, "WEB-INF/");
0097: File configDir = WriterUtils.initFile(fileDir, true);
0098:
0099: File catalogFile = WriterUtils.initWriteFile(new File(
0100: configDir, "catalog.xml"), false);
0101:
0102: try {
0103: Writer fw = new OutputStreamWriter(new FileOutputStream(
0104: catalogFile), getDefaultEncoding());
0105: storeCatalog(new WriterHelper(fw), data);
0106: fw.close();
0107: } catch (IOException e) {
0108: throw new ConfigurationException("Store" + root, e);
0109: }
0110:
0111: File dataDir;
0112:
0113: // if (!inDataDir) {
0114: // dataDir = WriterUtils.initFile(new File(root, "data/"), true);
0115: // } else {
0116: dataDir = root;
0117:
0118: // }
0119: File featureTypeDir = WriterUtils.initFile(new File(dataDir,
0120: "featureTypes/"), true);
0121: storeFeatures(featureTypeDir, data);
0122:
0123: File coverageDir = WriterUtils.initFile(new File(dataDir,
0124: "coverages/"), true);
0125: storeCoverages(coverageDir, data);
0126: }
0127:
0128: /**
0129: * Returns the default encoding for configuration files. For the moment we default to
0130: * UTF8, but we may want to make this user configurable (UTF-16 may be needed?)
0131: * @return
0132: */
0133: private static String getDefaultEncoding() {
0134: return "UTF-8";
0135: }
0136:
0137: public static void store(WCSDTO wcs, WMSDTO wms, WFSDTO wfs,
0138: GeoServerDTO geoServer, File root)
0139: throws ConfigurationException {
0140: if (LOGGER.isLoggable(Level.FINEST)) {
0141: LOGGER
0142: .finest("In method store WCSDTO,WMSDTO,WFSDTO, GeoServerDTO");
0143: }
0144:
0145: if (geoServer == null) {
0146: throw new ConfigurationException(
0147: "null parameter in store(WCSDTO,WMSDTO,WFSDTO, GeoServerDTO): cannot write.");
0148: }
0149:
0150: WriterUtils.initFile(root, true);
0151:
0152: // boolean inDataDir = GeoserverDataDirectory.isTrueDataDir();
0153:
0154: //We're just checking if it's actually a data_dir, not trying to
0155: //to do backwards compatibility. So if an old data_dir is made in
0156: //the old way, on save it'll come to the new way.
0157: File fileDir = root; //inDataDir ? root : new File(root, "WEB-INF/");
0158: File configDir = WriterUtils.initFile(fileDir, true);
0159: File configFile = WriterUtils.initWriteFile(new File(configDir,
0160: "services.xml"), false);
0161:
0162: try {
0163: Writer fw = new OutputStreamWriter(new FileOutputStream(
0164: configFile), getDefaultEncoding());
0165: storeServices(new WriterHelper(fw), wcs, wms, wfs,
0166: geoServer);
0167: fw.close();
0168: } catch (IOException e) {
0169: throw new ConfigurationException("Store" + root, e);
0170: }
0171: }
0172:
0173: public static void store(WCSDTO wcs, WMSDTO wms, WFSDTO wfs,
0174: GeoServerDTO geoServer, DataDTO data, File root)
0175: throws ConfigurationException {
0176: store(wcs, wms, wfs, geoServer, root);
0177: store(data, root);
0178: }
0179:
0180: /**
0181: * storeServices purpose.
0182: *
0183: * <p>
0184: * Writes the services.xml file from the model in memory.
0185: * </p>
0186: *
0187: * @param cw The Configuration Writer
0188: * @param wms DOCUMENT ME!
0189: * @param wfs DOCUMENT ME!
0190: * @param geoServer DOCUMENT ME!
0191: *
0192: * @throws ConfigurationException When an IO exception occurs.
0193: */
0194: protected static void storeServices(WriterHelper cw, WCSDTO wcs,
0195: WMSDTO wms, WFSDTO wfs, GeoServerDTO geoServer)
0196: throws ConfigurationException {
0197: if (LOGGER.isLoggable(Level.FINER)) {
0198: LOGGER.finer("In method storeServices");
0199: }
0200:
0201: cw.writeln("<?config.xml version=\"1.0\" encoding=\"UTF-8\"?>");
0202: cw.comment("Service level configuration");
0203: cw.openTag("serverConfiguration");
0204:
0205: GeoServerDTO g = geoServer;
0206:
0207: if (g != null) {
0208: cw.openTag("global");
0209:
0210: if (g.getLog4jConfigFile() != null) {
0211: cw.textTag("log4jConfigFile", g.getLog4jConfigFile());
0212: }
0213:
0214: cw.valueTag("suppressStdOutLogging", g
0215: .getSuppressStdOutLogging()
0216: + "");
0217:
0218: if (g.getLogLocation() != null) {
0219: cw.textTag("logLocation", g.getLogLocation());
0220: }
0221:
0222: cw.valueTag("JaiMemoryCapacity", ""
0223: + g.getJaiMemoryCapacity());
0224: cw.valueTag("JaiMemoryThreshold", ""
0225: + g.getJaiMemoryThreshold());
0226: cw.valueTag("JaiTileThreads", "" + g.getJaiTileThreads());
0227: cw.valueTag("JaiTilePriority", "" + g.getJaiTilePriority());
0228: cw.valueTag("JaiRecycling", "" + g.getJaiRecycling());
0229: cw.valueTag("ImageIOCache", "" + g.getImageIOCache());
0230: cw.valueTag("JaiJPEGNative", "" + g.getJaiJPEGNative());
0231: cw.valueTag("JaiPNGNative", "" + g.getJaiPNGNative());
0232:
0233: /*if(g.getBaseUrl()!=null && g.getBaseUrl()!=""){
0234: cw.comment("The base URL where this servlet will run. If running locally\n"+
0235: "then http://localhost:8080 (or whatever port you're running on)\n"+
0236: "should work. If you are serving to the world then this must be\n"+
0237: "the location where the geoserver servlets appear");
0238: cw.textTag("URL",g.getBaseUrl());
0239: }*/
0240: cw
0241: .comment("Sets the max number of Features returned by GetFeature");
0242: cw.valueTag("maxFeatures", "" + g.getMaxFeatures());
0243: cw
0244: .comment("Whether newlines and indents should be returned in \n"
0245: + "XML responses. Default is false");
0246: cw.valueTag("verbose", "" + g.isVerbose());
0247: cw
0248: .comment("Whether the Service Exceptions returned to clients should contain\n"
0249: + "full java stack traces (useful for debugging). ");
0250: cw.valueTag("verboseExceptions", ""
0251: + g.isVerboseExceptions());
0252: cw
0253: .comment("Sets the max number of decimal places past the zero returned in\n"
0254: + "a GetFeature response. Default is 4");
0255: cw.valueTag("numDecimals", "" + g.getNumDecimals());
0256:
0257: if (g.getCharSet() != null) {
0258: cw
0259: .comment("Sets the global character set. This could use some more testing\n"
0260: + "from international users, but what it does is sets the encoding\n"
0261: + "globally for all postgis database connections (the charset tag\n"
0262: + "in FeatureTypeConfig), as well as specifying the encoding in the return\n"
0263: + "config.xml header and mime type. The default is UTF-8. Also be warned\n"
0264: + "that GeoServer does not check if the CharSet is valid before\n"
0265: + "attempting to use it, so it will fail miserably if a bad charset\n"
0266: + "is used.");
0267: cw.valueTag("charSet", g.getCharSet().toString());
0268: }
0269:
0270: if ((g.getSchemaBaseUrl() != null)
0271: && (g.getSchemaBaseUrl() != "")) {
0272: cw
0273: .comment("Define a base url for the location of the wfs schemas.\n"
0274: + "By default GeoServer loads and references its own at\n"
0275: + "<URL>/data/capabilities. Uncomment to enable. The\n"
0276: + "standalone Tomcat server needs SchemaBaseUrl defined\n"
0277: + "for validation.");
0278: cw.textTag("SchemaBaseUrl", g.getSchemaBaseUrl());
0279: }
0280:
0281: if ((g.getProxyBaseUrl() != null)
0282: && (g.getSchemaBaseUrl() != "")) {
0283: cw
0284: .comment("Define a base url for the geoserver application.\n"
0285: + "By default GeoServer uses the local one, but it may "
0286: + "be wrong if you're using a reverse proxy in front of Geoserver");
0287: cw.textTag("ProxyBaseUrl", g.getProxyBaseUrl());
0288: }
0289:
0290: // removed, the user is now stored in the users.properties file
0291: // if ((g.getAdminUserName() != null) && (g.getAdminUserName() != "")) {
0292: // cw.comment("Defines the user name of the administrator for log in\n"
0293: // + "to the web based administration tool.");
0294: // cw.textTag("adminUserName", g.getAdminUserName());
0295: // }
0296: //
0297: // if ((g.getAdminPassword() != null) && (g.getAdminPassword() != "")) {
0298: // cw.comment("Defines the password of the administrator for log in\n"
0299: // + "to the web based administration tool.");
0300: // cw.textTag("adminPassword", g.getAdminPassword());
0301: // }
0302:
0303: if (g.getContact() != null) {
0304: storeContact(g.getContact(), cw);
0305: }
0306:
0307: if ((g.getTileCache() != null)
0308: && !"".equals(g.getTileCache().trim())) {
0309: cw
0310: .comment("Defines hte location of a tile cache (full url or relative path)");
0311: cw.textTag("tileCache", g.getTileCache());
0312: }
0313:
0314: cw.comment("Stores the current updateSequence");
0315: cw.textTag("updateSequence", g.getUpdateSequence() + "");
0316:
0317: cw.closeTag("global");
0318: }
0319:
0320: if (!((wcs == null) && (wfs == null) && (wms == null))) {
0321: cw.openTag("services");
0322:
0323: if (wcs != null) {
0324: storeService(wcs, cw);
0325: }
0326:
0327: if (wfs != null) {
0328: storeService(wfs, cw);
0329: }
0330:
0331: if (wms != null) {
0332: storeService(wms, cw);
0333: }
0334:
0335: // Z39.50 is not used in the current system.
0336: cw.closeTag("services");
0337: }
0338:
0339: cw.closeTag("serverConfiguration");
0340: }
0341:
0342: /**
0343: * storeContact purpose.
0344: *
0345: * <p>
0346: * Writes a contact into the WriterUtils provided from the ContactConfig
0347: * provided.
0348: * </p>
0349: *
0350: * @param c The ContactConfig to write.
0351: * @param cw The Configuration Writer
0352: *
0353: * @throws ConfigurationException When an IO exception occurs.
0354: */
0355: protected static void storeContact(ContactDTO c, WriterHelper cw)
0356: throws ConfigurationException {
0357: if (LOGGER.isLoggable(Level.FINER)) {
0358: LOGGER.finer("In method storeContact");
0359: }
0360:
0361: if ((c != null) && !c.equals(new ContactDTO())) {
0362: cw.openTag("ContactInformation");
0363: cw.openTag("ContactPersonPrimary");
0364: cw.textTag("ContactPerson", c.getContactPerson());
0365: cw.textTag("ContactOrganization", c
0366: .getContactOrganization());
0367: cw.closeTag("ContactPersonPrimary");
0368: cw.textTag("ContactPosition", c.getContactPosition());
0369: cw.openTag("ContactAddress");
0370: cw.textTag("AddressType", c.getAddressType());
0371: cw.textTag("Address", c.getAddress());
0372: cw.textTag("City", c.getAddressCity());
0373: cw.textTag("StateOrProvince", c.getAddressState());
0374: cw.textTag("PostCode", c.getAddressPostalCode());
0375: cw.textTag("Country", c.getAddressCountry());
0376: cw.closeTag("ContactAddress");
0377: cw.textTag("ContactVoiceTelephone", c.getContactVoice());
0378: cw.textTag("ContactFacsimileTelephone", c
0379: .getContactFacsimile());
0380: cw.textTag("ContactElectronicMailAddress", c
0381: .getContactEmail());
0382: cw.textTag("ContactOnlineResource", c.getOnlineResource());
0383: cw.closeTag("ContactInformation");
0384: }
0385: }
0386:
0387: /**
0388: * storeService purpose.
0389: *
0390: * <p>
0391: * Writes a service into the WriterUtils provided from the WFS or WMS
0392: * object provided.
0393: * </p>
0394: *
0395: * @param obj either a WFS or WMS object.
0396: * @param cw The Configuration Writer
0397: *
0398: * @throws ConfigurationException When an IO exception occurs or the object
0399: * provided is not of the correct type.
0400: */
0401: protected static void storeService(Object obj, WriterHelper cw)
0402: throws ConfigurationException {
0403: if (LOGGER.isLoggable(Level.FINER)) {
0404: LOGGER.finer("In method storeService");
0405: }
0406:
0407: ServiceDTO s = null;
0408: String u = null;
0409: String t = "";
0410:
0411: boolean fBounds = false;
0412: boolean srsXmlStyle = false;
0413: int serviceLevel = 0;
0414: String svgRenderer = null;
0415: Map baseMapLayers = null;
0416: Map baseMapStyles = null;
0417: Map baseMapEnvelopes = null;
0418: boolean svgAntiAlias = false;
0419: String allowInterpolation = null;
0420: boolean citeConformanceHacks = false;
0421:
0422: if (obj instanceof WCSDTO) {
0423: WCSDTO w = (WCSDTO) obj;
0424: s = w.getService();
0425: t = "WCS";
0426:
0427: //citeConformanceHacks = w.getCiteConformanceHacks();
0428: } else if (obj instanceof WFSDTO) {
0429: WFSDTO w = (WFSDTO) obj;
0430: s = w.getService();
0431: t = "WFS";
0432:
0433: fBounds = w.isFeatureBounding();
0434: srsXmlStyle = w.isSrsXmlStyle();
0435: serviceLevel = w.getServiceLevel();
0436: citeConformanceHacks = w.getCiteConformanceHacks();
0437: } else if (obj instanceof WMSDTO) {
0438: WMSDTO w = (WMSDTO) obj;
0439: s = w.getService();
0440: t = "WMS";
0441: svgRenderer = w.getSvgRenderer();
0442: svgAntiAlias = w.getSvgAntiAlias();
0443: allowInterpolation = w.getAllowInterpolation();
0444: baseMapLayers = w.getBaseMapLayers();
0445: baseMapStyles = w.getBaseMapStyles();
0446: baseMapEnvelopes = w.getBaseMapEnvelopes();
0447: } else {
0448: throw new ConfigurationException(
0449: "Invalid object: not WMS or WFS or WCS");
0450: }
0451:
0452: Map atrs = new HashMap();
0453: atrs.put("type", t);
0454: atrs.put("enabled", s.isEnabled() + "");
0455: cw.openTag("service", atrs);
0456: cw
0457: .comment("ServiceDTO elements, needed for the capabilities document\n"
0458: + "Title and OnlineResource are the two required");
0459:
0460: if ((s.getName() != null) && (s.getName() != "")) {
0461: cw.textTag("name", s.getName());
0462: }
0463:
0464: if ((s.getTitle() != null) && (s.getTitle() != "")) {
0465: cw.textTag("title", s.getTitle());
0466: }
0467:
0468: if ((s.getAbstract() != null) && (s.getAbstract() != "")) {
0469: cw.textTag("abstract", s.getAbstract());
0470: }
0471:
0472: if (s.getMetadataLink() != null) {
0473: MetaDataLink ml = s.getMetadataLink();
0474: Map mlAttr = new HashMap();
0475: mlAttr.put("about", ml.getAbout());
0476: mlAttr.put("type", ml.getType());
0477: mlAttr.put("metadataType", ml.getMetadataType());
0478: cw.textTag("metadataLink", mlAttr, ml.getContent());
0479: }
0480:
0481: if (!s.getKeywords().isEmpty()) {
0482: cw.openTag("keywords");
0483:
0484: for (int i = 0; i < s.getKeywords().size(); i++) {
0485: String str = s.getKeywords().get(i).toString();
0486: cw.textTag("keyword", str.replaceAll("\\r", ""));
0487: }
0488:
0489: cw.closeTag("keywords");
0490: }
0491:
0492: if (s.getOnlineResource() != null) {
0493: cw.textTag("onlineResource", s.getOnlineResource()
0494: .toString());
0495: }
0496:
0497: if ((s.getFees() != null) && (s.getFees() != "")) {
0498: cw.textTag("fees", s.getFees());
0499: }
0500:
0501: if ((s.getAccessConstraints() != null)
0502: && (s.getAccessConstraints() != "")) {
0503: cw.textTag("accessConstraints", s.getAccessConstraints());
0504: }
0505:
0506: if (fBounds) {
0507: cw.valueTag("featureBounding", fBounds + "");
0508: }
0509:
0510: //if (srsXmlStyle) {
0511: cw.valueTag("srsXmlStyle", srsXmlStyle + "");
0512:
0513: //}
0514: if (serviceLevel != 0) {
0515: cw.valueTag("serviceLevel", serviceLevel + "");
0516: }
0517:
0518: if (obj instanceof WFSDTO) //DJB: this method (storeService) doesnt separate WFS and WMS very well!
0519: {
0520: cw.textTag("citeConformanceHacks", citeConformanceHacks
0521: + "");
0522: }
0523:
0524: if ((s.getMaintainer() != null) && (s.getMaintainer() != "")) {
0525: cw.textTag("maintainer", s.getMaintainer());
0526: }
0527:
0528: if (svgRenderer != null) {
0529: cw.textTag("svgRenderer", svgRenderer);
0530: }
0531:
0532: if ((baseMapLayers != null) && (baseMapStyles != null)
0533: && (baseMapEnvelopes != null)) {
0534: cw.openTag("BaseMapGroups");
0535:
0536: // for each title/layer combo, write it out
0537: String[] titles = (String[]) baseMapLayers.keySet()
0538: .toArray(new String[0]);
0539:
0540: for (int i = 0; i < titles.length; i++) {
0541: HashMap titleMap = new HashMap();
0542: titleMap.put("baseMapTitle", titles[i]);
0543: cw.openTag("BaseMapGroup", titleMap);
0544: cw.textTag("baseMapLayers", (String) baseMapLayers
0545: .get(titles[i]));
0546: cw.textTag("baseMapStyles", (String) baseMapStyles
0547: .get(titles[i]));
0548:
0549: GeneralEnvelope e = (GeneralEnvelope) baseMapEnvelopes
0550: .get(titles[i]);
0551: Map m = new HashMap();
0552:
0553: m.put("srsName", e.getCoordinateReferenceSystem()
0554: .getIdentifiers().toArray()[0].toString());
0555:
0556: if (!e.isNull()) {
0557: cw.openTag("baseMapEnvelope", m);
0558: cw.textTag("pos", e.getLowerCorner().getOrdinate(0)
0559: + " " + e.getLowerCorner().getOrdinate(1));
0560: cw.textTag("pos", e.getUpperCorner().getOrdinate(0)
0561: + " " + e.getUpperCorner().getOrdinate(1));
0562: cw.closeTag("baseMapEnvelope");
0563: }
0564:
0565: cw.closeTag("BaseMapGroup");
0566: }
0567:
0568: cw.closeTag("BaseMapGroups");
0569: }
0570:
0571: if (obj instanceof WMSDTO) {
0572: cw.textTag("svgAntiAlias", svgAntiAlias + "");
0573:
0574: if (allowInterpolation != null) {
0575: cw.textTag("allowInterpolation", allowInterpolation);
0576: }
0577: }
0578:
0579: if ((s.getStrategy() != null) && !"".equals(s.getStrategy())) {
0580: cw.textTag("serviceStrategy", s.getStrategy());
0581: }
0582:
0583: if (s.getPartialBufferSize() != 0) {
0584: cw.textTag("partialBufferSize", s.getPartialBufferSize()
0585: + "");
0586: }
0587:
0588: cw.closeTag("service");
0589: }
0590:
0591: /**
0592: * storeCatalog purpose.
0593: *
0594: * <p>
0595: * Writes a catalog into the WriterUtils provided from Data provided in
0596: * memory.
0597: * </p>
0598: *
0599: * @param cw The Configuration Writer
0600: * @param data DOCUMENT ME!
0601: *
0602: * @throws ConfigurationException When an IO exception occurs.
0603: */
0604: protected static void storeCatalog(WriterHelper cw, DataDTO data)
0605: throws ConfigurationException {
0606: if (LOGGER.isLoggable(Level.FINER)) {
0607: LOGGER.finer("In method storeCatalog");
0608: }
0609:
0610: cw.writeln("<?config.xml version=\"1.0\" encoding=\"UTF-8\"?>");
0611: cw.openTag("catalog");
0612:
0613: //DJB: this used to not put in a datastores tag if there were none defined.
0614: // this caused the loader to blow up. I changed it so it puts an empty <datastore> here!
0615: cw.openTag("datastores");
0616: cw
0617: .comment("a datastore configuration element serves as a common data source connection\n"
0618: + "parameters repository for all featuretypes it holds.");
0619:
0620: Iterator i = data.getDataStores().keySet().iterator();
0621:
0622: while (i.hasNext()) {
0623: String s = (String) i.next();
0624: DataStoreInfoDTO ds = (DataStoreInfoDTO) data
0625: .getDataStores().get(s);
0626:
0627: if (ds != null) {
0628: storeDataStore(cw, ds);
0629: }
0630: }
0631:
0632: cw.closeTag("datastores");
0633:
0634: //DJB: since datastore screws up if the tag is missing, I'm fixing it here too
0635: cw.openTag("formats");
0636: cw
0637: .comment("a format configuration element serves as a common data source\n"
0638: + "parameters repository for all coverages it holds.");
0639:
0640: i = data.getFormats().keySet().iterator();
0641:
0642: while (i.hasNext()) {
0643: String s = (String) i.next();
0644: CoverageStoreInfoDTO df = (CoverageStoreInfoDTO) data
0645: .getFormats().get(s);
0646:
0647: if (df != null) {
0648: storeFormat(cw, df);
0649: }
0650: }
0651:
0652: cw.closeTag("formats");
0653: cw.comment("Defines namespaces to be used by the datastores.");
0654: cw.openTag("namespaces");
0655:
0656: i = data.getNameSpaces().keySet().iterator();
0657:
0658: while (i.hasNext()) {
0659: String s = (String) i.next();
0660: NameSpaceInfoDTO ns = (NameSpaceInfoDTO) data
0661: .getNameSpaces().get(s);
0662:
0663: if (ns != null) {
0664: storeNameSpace(cw, ns);
0665: }
0666: }
0667:
0668: cw.closeTag("namespaces");
0669:
0670: //DJB: since datastore screws up if the tag is missing, I'm fixing it here too
0671: cw.openTag("styles");
0672: cw
0673: .comment("Defines the style ids and file name to be used by the wms.");
0674:
0675: i = data.getStyles().keySet().iterator();
0676:
0677: while (i.hasNext()) {
0678: String s = (String) i.next();
0679: StyleDTO st = (StyleDTO) data.getStyles().get(s);
0680:
0681: if (st != null) {
0682: storeStyle(cw, st);
0683: }
0684: }
0685:
0686: cw.closeTag("styles");
0687:
0688: cw.closeTag("catalog");
0689: }
0690:
0691: /**
0692: * storeDataStore purpose.
0693: *
0694: * <p>
0695: * Writes a DataStoreInfo into the WriterUtils provided.
0696: * </p>
0697: *
0698: * @param cw The Configuration Writer
0699: * @param ds The Datastore.
0700: *
0701: * @throws ConfigurationException When an IO exception occurs.
0702: */
0703: protected static void storeDataStore(WriterHelper cw,
0704: DataStoreInfoDTO ds) throws ConfigurationException {
0705: if (LOGGER.isLoggable(Level.FINER)) {
0706: LOGGER.finer("In method storeDataStore");
0707: }
0708:
0709: Map temp = new HashMap();
0710:
0711: if (ds.getId() != null) {
0712: temp.put("id", ds.getId());
0713: }
0714:
0715: temp.put("enabled", ds.isEnabled() + "");
0716:
0717: if (ds.getNameSpaceId() != null) {
0718: temp.put("namespace", ds.getNameSpaceId());
0719: }
0720:
0721: cw.openTag("datastore", temp);
0722:
0723: if ((ds.getAbstract() != null) && (ds.getAbstract() != "")) {
0724: cw.textTag("abstract", ds.getAbstract());
0725: }
0726:
0727: if ((ds.getTitle() != null) && (ds.getTitle() != "")) {
0728: cw.textTag("title", ds.getTitle());
0729: }
0730:
0731: if (ds.getConnectionParams().size() != 0) {
0732: cw.openTag("connectionParams");
0733:
0734: Iterator i = ds.getConnectionParams().keySet().iterator();
0735: temp = new HashMap();
0736:
0737: while (i.hasNext()) {
0738: String key = (String) i.next();
0739: temp.put("name", key);
0740: temp.put("value", ds.getConnectionParams().get(key)
0741: .toString());
0742: cw.attrTag("parameter", temp);
0743: }
0744:
0745: cw.closeTag("connectionParams");
0746: }
0747:
0748: cw.closeTag("datastore");
0749: }
0750:
0751: /**
0752: * storeFormat purpose.
0753: *
0754: * <p>
0755: * Writes a CoverageStoreInfo into the WriterUtils provided.
0756: * </p>
0757: *
0758: * @param cw The Configuration Writer
0759: * @param store The Format.
0760: *
0761: * @throws ConfigurationException When an IO exception occurs.
0762: */
0763: protected static void storeFormat(WriterHelper cw,
0764: CoverageStoreInfoDTO df) throws ConfigurationException {
0765: if (LOGGER.isLoggable(Level.FINE)) {
0766: LOGGER.fine("In method storeFormat");
0767: }
0768:
0769: Map temp = new HashMap();
0770:
0771: if (df.getId() != null) {
0772: temp.put("id", df.getId());
0773: }
0774:
0775: temp.put("enabled", df.isEnabled() + "");
0776:
0777: if (df.getNameSpaceId() != null) {
0778: temp.put("namespace", df.getNameSpaceId());
0779: }
0780:
0781: cw.openTag("format", temp);
0782:
0783: if ((df.getAbstract() != null) && (df.getAbstract() != "")) {
0784: cw.textTag("description", df.getAbstract());
0785: }
0786:
0787: if ((df.getTitle() != null) && (df.getTitle() != "")) {
0788: cw.textTag("title", df.getTitle());
0789: }
0790:
0791: if ((df.getType() != null) && (df.getType() != "")) {
0792: cw.textTag("type", df.getType());
0793: }
0794:
0795: if ((df.getUrl() != null) && (df.getUrl() != "")) {
0796: cw.textTag("url", df.getUrl());
0797: }
0798:
0799: cw.closeTag("format");
0800: }
0801:
0802: /**
0803: * storeNameSpace purpose.
0804: *
0805: * <p>
0806: * Writes a NameSpaceInfoDTO into the WriterUtils provided.
0807: * </p>
0808: *
0809: * @param cw The Configuration Writer
0810: * @param ns The NameSpaceInfo.
0811: *
0812: * @throws ConfigurationException When an IO exception occurs.
0813: */
0814: protected static void storeNameSpace(WriterHelper cw,
0815: NameSpaceInfoDTO ns) throws ConfigurationException {
0816: if (LOGGER.isLoggable(Level.FINER)) {
0817: LOGGER.finer("In method storeNameSpace");
0818: }
0819:
0820: Map attr = new HashMap();
0821:
0822: if ((ns.getUri() != null) && (ns.getUri() != "")) {
0823: attr.put("uri", ns.getUri());
0824: }
0825:
0826: if ((ns.getPrefix() != null) && (ns.getPrefix() != "")) {
0827: attr.put("prefix", ns.getPrefix());
0828: }
0829:
0830: if (ns.isDefault()) {
0831: attr.put("default", "true");
0832: }
0833:
0834: if (attr.size() != 0) {
0835: cw.attrTag("namespace", attr);
0836: }
0837: }
0838:
0839: /**
0840: * storeStyle purpose.
0841: *
0842: * <p>
0843: * Writes a StyleDTO into the WriterUtils provided.
0844: * </p>
0845: *
0846: * @param cw The Configuration Writer
0847: * @param s The StyleDTO.
0848: *
0849: * @throws ConfigurationException When an IO exception occurs.
0850: */
0851: protected static void storeStyle(WriterHelper cw, StyleDTO s)
0852: throws ConfigurationException {
0853: if (LOGGER.isLoggable(Level.FINER)) {
0854: LOGGER.finer(new StringBuffer("In method storeStyle: ")
0855: .append(s).toString());
0856: }
0857:
0858: Map attr = new HashMap();
0859:
0860: if ((s.getId() != null) && (s.getId() != "")) {
0861: attr.put("id", s.getId());
0862: }
0863:
0864: if (s.getFilename() != null) {
0865: attr.put("filename", s.getFilename().getName());
0866: }
0867:
0868: if (s.isDefault()) {
0869: attr.put("default", "true");
0870: }
0871:
0872: if (LOGGER.isLoggable(Level.FINER)) {
0873: LOGGER.finer(new StringBuffer("storing style ")
0874: .append(attr).toString());
0875: }
0876:
0877: if (attr.size() != 0) {
0878: cw.attrTag("style", attr);
0879: }
0880: }
0881:
0882: /**
0883: * storeStyle purpose.
0884: *
0885: * <p>
0886: * Sets up writing FeatureTypes into their Directories.
0887: * </p>
0888: *
0889: * @param dir The FeatureTypes directory
0890: * @param data DOCUMENT ME!
0891: *
0892: * @throws ConfigurationException When an IO exception occurs.
0893: *
0894: * @see storeFeature(FeatureTypeInfo,File)
0895: */
0896: protected static void storeFeatures(File dir, DataDTO data)
0897: throws ConfigurationException {
0898: if (LOGGER.isLoggable(Level.FINER)) {
0899: LOGGER.finer("In method storeFeatures");
0900: }
0901:
0902: // write them
0903: Iterator i = data.getFeaturesTypes().keySet().iterator();
0904:
0905: while (i.hasNext()) {
0906: String s = (String) i.next();
0907: FeatureTypeInfoDTO ft = (FeatureTypeInfoDTO) data
0908: .getFeaturesTypes().get(s);
0909:
0910: if (ft != null) {
0911: String ftDirName = ft.getDirName();
0912:
0913: try { // encode the file name (this is to catch colons in FT names)
0914: ftDirName = URLEncoder.encode(ftDirName,
0915: getDefaultEncoding());
0916:
0917: if (LOGGER.isLoggable(Level.FINER)) {
0918: LOGGER.finer(new StringBuffer(
0919: "Writing encoded URL: ").append(
0920: ftDirName).toString());
0921: }
0922: } catch (UnsupportedEncodingException e1) {
0923: throw new ConfigurationException(e1);
0924: }
0925:
0926: File dir2 = WriterUtils.initWriteFile(new File(dir,
0927: ftDirName), true);
0928:
0929: storeFeature(ft, dir2);
0930:
0931: if (ft.getSchemaAttributes() != null) {
0932: if (LOGGER.isLoggable(Level.FINER)) {
0933: LOGGER
0934: .finer(new StringBuffer(ft.getKey())
0935: .append(
0936: " writing schema.xml w/ ")
0937: .append(
0938: ft
0939: .getSchemaAttributes()
0940: .size())
0941: .toString());
0942: }
0943:
0944: storeFeatureSchema(ft, dir2);
0945: }
0946: }
0947: }
0948:
0949: // delete old ones that are not overwritten
0950: //I'm changing this action, as it is directly leading to users not
0951: //being able to create their own shapefiles in the web admin tool.
0952: //since their shit always gets deleted. The behaviour has now changed
0953: //to just getting rid of the geoserver config files, info.xml and
0954: //schema.xml and leaving any others. We should revisit this, I
0955: //do think getting rid of stale featureTypes is a good thing. For 1.3
0956: //I want to look into directly uploading shapefiles, and perhaps they
0957: //would then go in a 'shapefile' directory, next to featureTypes or
0958: //or something, so that the featureTypes directory only contains
0959: //the info, and schema and those sorts of files. But I do kind of like
0960: //being able to access the shapefiles directly from the web app, and
0961: //indeed have had thoughts of expanding that, so that users could
0962: //always download the full shape for a layer, generated automatically
0963: //if it's from another datastore. Though I suppose that is not
0964: //mutually exclusive, just a little wasting of space, for shapefiles
0965: //would be held twice.
0966: File[] fa = dir.listFiles();
0967:
0968: for (int j = 0; j < fa.length; j++) {
0969: // find dir name
0970: i = data.getFeaturesTypes().values().iterator();
0971:
0972: FeatureTypeInfoDTO fti = null;
0973:
0974: while ((fti == null) && i.hasNext()) {
0975: FeatureTypeInfoDTO ft = (FeatureTypeInfoDTO) i.next();
0976: String ftDirName = ft.getDirName();
0977:
0978: try { // encode the file name (this is to catch colons in FT names)
0979: ftDirName = URLEncoder.encode(ftDirName,
0980: getDefaultEncoding());
0981:
0982: if (LOGGER.isLoggable(Level.FINER)) {
0983: LOGGER.finer(new StringBuffer("Decoded URL: ")
0984: .append(ftDirName).toString());
0985: }
0986: } catch (UnsupportedEncodingException e1) {
0987: throw new ConfigurationException(e1);
0988: }
0989:
0990: if (ftDirName.equals(fa[j].getName())) {
0991: fti = ft;
0992: }
0993: }
0994:
0995: if (fti == null) {
0996: //delete it
0997: File[] files = fa[j].listFiles();
0998:
0999: if (files != null) {
1000: for (int x = 0; x < files.length; x++) {
1001: //hold on to the data, but be sure to get rid of the
1002: //geoserver config shit, as these were deleted.
1003: if (files[x].getName().equals("info.xml")
1004: || files[x].getName().equals(
1005: "schema.xml")) {
1006: //sorry for the hardcodes, I don't remember if/where
1007: //we have these file names.
1008: files[x].delete();
1009: }
1010: }
1011: }
1012:
1013: if ((files != null) && (files.length == 0)) {
1014: fa[j].delete();
1015: }
1016: }
1017: }
1018: }
1019:
1020: /**
1021: * storeStyle purpose.
1022: *
1023: * <p>
1024: * Writes a FeatureTypes into it's Directory.
1025: * </p>
1026: *
1027: * @param ft DOCUMENT ME!
1028: * @param dir The particular FeatureTypeInfo directory
1029: *
1030: * @throws ConfigurationException When an IO exception occurs.
1031: *
1032: * @see storeFeatures(File)
1033: */
1034: protected static void storeFeature(FeatureTypeInfoDTO ft, File dir)
1035: throws ConfigurationException {
1036: if (LOGGER.isLoggable(Level.FINER)) {
1037: LOGGER.finer("In method storeFeature");
1038: }
1039:
1040: File f = WriterUtils.initWriteFile(new File(dir, "info.xml"),
1041: false);
1042:
1043: try {
1044: Writer fw = new OutputStreamWriter(new FileOutputStream(f),
1045: getDefaultEncoding());
1046: WriterHelper cw = new WriterHelper(fw);
1047: Map m = new HashMap();
1048:
1049: // oh the horror, a string comparison using !=... well, this
1050: // class is going to die soon so I won't touch it...
1051: if ((ft.getDataStoreId() != null)
1052: && (ft.getDataStoreId() != "")) {
1053: m.put("datastore", ft.getDataStoreId());
1054: }
1055:
1056: cw.openTag("featureType", m);
1057:
1058: if ((ft.getName() != null) && (ft.getName() != "")) {
1059: cw.textTag("name", ft.getName());
1060: }
1061:
1062: if ((ft.getAlias() != null) && !ft.getAlias().equals("")) {
1063: cw.textTag("alias", ft.getAlias());
1064: }
1065:
1066: cw
1067: .comment("native wich EPGS code for the FeatureTypeInfoDTO");
1068: cw.textTag("SRS", ft.getSRS() + "");
1069:
1070: cw.textTag("SRSHandling", String.valueOf(ft
1071: .getSRSHandling()));
1072:
1073: if ((ft.getTitle() != null) && (ft.getTitle() != "")) {
1074: cw.textTag("title", ft.getTitle());
1075: }
1076:
1077: if ((ft.getAbstract() != null) && (ft.getAbstract() != "")) {
1078: cw.textTag("abstract", ft.getAbstract());
1079: }
1080:
1081: if ((ft.getWmsPath() != null) && (ft.getWmsPath() != "")) {
1082: cw.textTag("wmspath", ft.getWmsPath());
1083: }
1084:
1085: cw.valueTag("numDecimals", ft.getNumDecimals() + "");
1086:
1087: if ((ft.getKeywords() != null)
1088: && (ft.getKeywords().size() != 0)) {
1089: String s = "";
1090: Iterator i = ft.getKeywords().iterator();
1091:
1092: if (i.hasNext()) {
1093: s = i.next().toString();
1094:
1095: while (i.hasNext()) {
1096: s = s + ", " + i.next().toString();
1097: }
1098: }
1099:
1100: cw.textTag("keywords", s);
1101: }
1102:
1103: if ((ft.getMetadataLinks() != null)
1104: && (ft.getMetadataLinks().size() != 0)) {
1105: cw.openTag("metadataLinks");
1106:
1107: for (Iterator it = ft.getMetadataLinks().iterator(); it
1108: .hasNext();) {
1109: MetaDataLink ml = (MetaDataLink) it.next();
1110: Map mlAttr = new HashMap();
1111: mlAttr.put("about", ml.getAbout());
1112: mlAttr.put("type", ml.getType());
1113: mlAttr.put("metadataType", ml.getMetadataType());
1114: cw.textTag("metadataLink", mlAttr, ml.getContent());
1115: }
1116:
1117: cw.closeTag("metadataLinks");
1118: }
1119:
1120: if (ft.getLatLongBBox() != null) {
1121: m = new HashMap();
1122:
1123: Envelope e = ft.getLatLongBBox();
1124:
1125: // from creation, isn't stored otherwise
1126: if (!e.isNull()) {
1127: m.put("dynamic", "false");
1128: m.put("minx", e.getMinX() + "");
1129: m.put("miny", e.getMinY() + "");
1130: m.put("maxx", e.getMaxX() + "");
1131: m.put("maxy", e.getMaxY() + "");
1132: } else {
1133: m.put("dynamic", "true");
1134: }
1135:
1136: cw.attrTag("latLonBoundingBox", m);
1137: }
1138:
1139: if (ft.getNativeBBox() != null) {
1140: m = new HashMap();
1141:
1142: Envelope e = ft.getNativeBBox();
1143:
1144: // from creation, isn't stored otherwise
1145: if (!e.isNull()) {
1146: m.put("dynamic", "false");
1147: m.put("minx", e.getMinX() + "");
1148: m.put("miny", e.getMinY() + "");
1149: m.put("maxx", e.getMaxX() + "");
1150: m.put("maxy", e.getMaxY() + "");
1151: } else {
1152: m.put("dynamic", "true");
1153: }
1154:
1155: cw.attrTag("nativeBBox", m);
1156: }
1157:
1158: if ((ft.getDefaultStyle() != null)
1159: && (ft.getDefaultStyle() != "")) {
1160: cw
1161: .comment("the default style this FeatureTypeInfoDTO can be represented by.\n"
1162: + "at least must contain the \"default\" attribute ");
1163: m = new HashMap();
1164: m.put("default", ft.getDefaultStyle());
1165:
1166: final ArrayList styles = ft.getStyles();
1167:
1168: if (styles.isEmpty()) {
1169: cw.attrTag("styles", m);
1170: } else {
1171: cw.openTag("styles", m);
1172:
1173: Iterator s_IT = styles.iterator();
1174:
1175: while (s_IT.hasNext())
1176: cw.textTag("style", (String) s_IT.next());
1177:
1178: cw.closeTag("styles");
1179: }
1180: }
1181:
1182: m = new HashMap();
1183:
1184: if (ft.getCacheMaxAge() != null) {
1185: m.put("maxage", ft.getCacheMaxAge());
1186: }
1187:
1188: if (ft.isCachingEnabled()) {
1189: m.put("enabled", "true");
1190: } else {
1191: m.put("enabled", "false");
1192: }
1193:
1194: cw.attrTag("cacheinfo", m);
1195:
1196: if (ft.getDefinitionQuery() != null) {
1197: cw.openTag("definitionQuery");
1198:
1199: /*
1200: * @REVISIT: strongly test this works.
1201: */
1202:
1203: /*
1204: StringWriter sw = new StringWriter();
1205: org.geotools.filter.XMLEncoder xe = new org.geotools.filter.XMLEncoder(sw);
1206: xe.encode(ft.getDefinitionQuery());
1207: cw.writeln(sw.toString());
1208: cw.closeTag("definitionQuery");
1209: */
1210: FilterTransformer ftransformer = new FilterTransformer();
1211: ftransformer.setOmitXMLDeclaration(true);
1212: ftransformer.setNamespaceDeclarationEnabled(false);
1213:
1214: String sfilter = ftransformer.transform(ft
1215: .getDefinitionQuery());
1216: cw.writeln(sfilter);
1217: }
1218:
1219: cw.textTag("maxFeatures", String.valueOf(ft
1220: .getMaxFeatures()));
1221:
1222: cw.closeTag("featureType");
1223: fw.close();
1224: } catch (IOException e) {
1225: throw new ConfigurationException(e);
1226: } catch (TransformerException e) {
1227: throw new ConfigurationException(e);
1228: }
1229: }
1230:
1231: protected static void storeFeatureSchema(FeatureTypeInfoDTO fs,
1232: File dir) throws ConfigurationException {
1233: if ((fs.getSchemaBase() == null) || (fs.getSchemaBase() == "")) {
1234: //LOGGER.info( "No schema base" );
1235: if (LOGGER.isLoggable(Level.FINER)) {
1236: LOGGER.finer(new StringBuffer(fs.getKey()).append(
1237: " has not schemaBase").toString());
1238: }
1239:
1240: return;
1241: }
1242:
1243: if ((fs.getSchemaName() == null) || (fs.getSchemaName() == "")) {
1244: // Should assume Null?
1245: //LOGGER.info( "No schema name" ); // Do we even have a field for this?
1246: if (LOGGER.isLoggable(Level.FINER)) {
1247: LOGGER.finer(new StringBuffer(fs.getKey()).append(
1248: " has not schemaName").toString());
1249: }
1250:
1251: return;
1252: }
1253:
1254: File f = WriterUtils.initWriteFile(new File(dir, "schema.xml"),
1255: false);
1256:
1257: try {
1258: Writer fw = new OutputStreamWriter(new FileOutputStream(f),
1259: getDefaultEncoding());
1260: storeFeatureSchema(fs, fw);
1261: fw.close();
1262: } catch (IOException e) {
1263: throw new ConfigurationException(e);
1264: }
1265: }
1266:
1267: public static void storeFeatureSchema(FeatureTypeInfoDTO fs,
1268: Writer w) throws ConfigurationException {
1269: WriterHelper cw = new WriterHelper(w);
1270: HashMap m = new HashMap();
1271: String t = fs.getSchemaName();
1272:
1273: if (t != null) {
1274: if (!"_Type".equals(t.substring(t.length() - 5))) {
1275: t = t + "_Type";
1276: }
1277:
1278: m.put("name", t);
1279: }
1280:
1281: cw.openTag("xs:complexType", m);
1282: cw.openTag("xs:complexContent");
1283: m = new HashMap();
1284: t = fs.getSchemaBase();
1285:
1286: if (t != null) {
1287: m.put("base", t);
1288: }
1289:
1290: cw.openTag("xs:extension", m);
1291: cw.openTag("xs:sequence");
1292:
1293: for (int i = 0; i < fs.getSchemaAttributes().size(); i++) {
1294: AttributeTypeInfoDTO ati = (AttributeTypeInfoDTO) fs
1295: .getSchemaAttributes().get(i);
1296: m = new HashMap();
1297: m.put("nillable", "" + ati.isNillable());
1298: m.put("minOccurs", "" + ati.getMinOccurs());
1299: m.put("maxOccurs", "" + ati.getMaxOccurs());
1300:
1301: NameSpaceTranslator nst_xs = NameSpaceTranslatorFactory
1302: .getInstance().getNameSpaceTranslator("xs");
1303: NameSpaceTranslator nst_gml = NameSpaceTranslatorFactory
1304: .getInstance().getNameSpaceTranslator("gml");
1305:
1306: if (!ati.isComplex()) {
1307: if (ati.getName() == ati.getType()) {
1308: String r = "";
1309: NameSpaceElement nse = nst_xs.getElement(ati
1310: .getType());
1311:
1312: if (nse == null) {
1313: nse = nst_gml.getElement(ati.getType());
1314: }
1315:
1316: r = nse.getQualifiedTypeRefName();
1317: m.put("ref", r);
1318: } else {
1319: m.put("name", ati.getName());
1320:
1321: String r = "";
1322: NameSpaceElement nse = nst_xs.getElement(ati
1323: .getType());
1324:
1325: if (nse == null) {
1326: nse = nst_gml.getElement(ati.getType());
1327: r = nse.getQualifiedTypeDefName(); // Def
1328: } else {
1329: r = nse.getQualifiedTypeRefName(); // Ref
1330: }
1331:
1332: m.put("type", r);
1333: }
1334:
1335: cw.attrTag("xs:element", m);
1336: } else {
1337: m.put("name", ati.getName());
1338: cw.openTag("xs:element", m);
1339: cw.writeln(ati.getType());
1340: cw.closeTag("xs:element");
1341: }
1342: }
1343:
1344: cw.closeTag("xs:sequence");
1345: cw.closeTag("xs:extension");
1346: cw.closeTag("xs:complexContent");
1347: cw.closeTag("xs:complexType");
1348: }
1349:
1350: protected static void storeCoverages(File dir, DataDTO data)
1351: throws ConfigurationException {
1352: if (LOGGER.isLoggable(Level.FINE)) {
1353: LOGGER.fine("In method storeCoverages");
1354: }
1355:
1356: // write them
1357: Iterator i = data.getCoverages().keySet().iterator();
1358:
1359: while (i.hasNext()) {
1360: String s = (String) i.next();
1361: CoverageInfoDTO cv = (CoverageInfoDTO) data.getCoverages()
1362: .get(s);
1363:
1364: if (cv != null) {
1365: File dir2 = WriterUtils.initWriteFile(new File(dir, cv
1366: .getDirName()), true);
1367:
1368: storeCoverage(cv, dir2);
1369: }
1370: }
1371:
1372: File[] fa = dir.listFiles();
1373:
1374: for (int j = 0; j < fa.length; j++) {
1375: if (fa[j].isDirectory()) {
1376: // find dir name
1377: i = data.getCoverages().values().iterator();
1378:
1379: CoverageInfoDTO cvi = null;
1380:
1381: while ((cvi == null) && i.hasNext()) {
1382: CoverageInfoDTO cv = (CoverageInfoDTO) i.next();
1383:
1384: if (cv.getDirName().equals(fa[j].getName())) {
1385: cvi = cv;
1386: }
1387: }
1388:
1389: if (cvi == null) {
1390: //delete it
1391: File[] t = fa[j].listFiles();
1392:
1393: if (t != null) {
1394: for (int x = 0; x < t.length; x++) {
1395: //hold on to the data, but be sure to get rid of the
1396: //geoserver config shit, as these were deleted.
1397: if (t[x].getName().equals("info.xml")) {
1398: //sorry for the hardcodes, I don't remember if/where
1399: //we have these file names.
1400: t[x].delete();
1401: }
1402: }
1403: }
1404:
1405: if (fa[j].listFiles().length == 0) {
1406: fa[j].delete();
1407: }
1408: }
1409: }
1410: }
1411: }
1412:
1413: protected static void storeCoverage(CoverageInfoDTO cv, File dir)
1414: throws ConfigurationException {
1415: if (LOGGER.isLoggable(Level.FINE)) {
1416: LOGGER.fine("In method storeCoverage");
1417: }
1418:
1419: File f = WriterUtils.initWriteFile(new File(dir, "info.xml"),
1420: false);
1421:
1422: try {
1423: Writer fw = new OutputStreamWriter(new FileOutputStream(f),
1424: getDefaultEncoding());
1425: WriterHelper cw = new WriterHelper(fw);
1426: Map m = new HashMap();
1427:
1428: if ((cv.getFormatId() != null) && (cv.getFormatId() != "")) {
1429: m.put("format", cv.getFormatId());
1430: }
1431:
1432: cw.openTag("coverage", m);
1433:
1434: if ((cv.getName() != null) && (cv.getName() != "")) {
1435: cw.textTag("name", cv.getName());
1436: }
1437:
1438: if ((cv.getLabel() != null) && (cv.getLabel() != "")) {
1439: cw.textTag("label", cv.getLabel());
1440: }
1441:
1442: if ((cv.getDescription() != null)
1443: && (cv.getDescription() != "")) {
1444: cw.textTag("description", cv.getDescription());
1445: }
1446:
1447: if ((cv.getWmsPath() != null) && (cv.getWmsPath() != "")) {
1448: cw.textTag("wmspath", cv.getWmsPath());
1449: }
1450:
1451: m = new HashMap();
1452:
1453: if ((cv.getMetadataLink() != null)) {
1454: m.put("about", cv.getMetadataLink().getAbout());
1455: m.put("type", cv.getMetadataLink().getType());
1456: m.put("metadataType", cv.getMetadataLink()
1457: .getMetadataType());
1458:
1459: cw.openTag("metadataLink", m);
1460: cw.writeln(cv.getMetadataLink().getContent());
1461: cw.closeTag("metadataLink");
1462: }
1463:
1464: if ((cv.getKeywords() != null)
1465: && (cv.getKeywords().size() != 0)) {
1466: String s = "";
1467: Iterator i = cv.getKeywords().iterator();
1468:
1469: if (i.hasNext()) {
1470: s = i.next().toString();
1471:
1472: while (i.hasNext()) {
1473: s = s + "," + i.next().toString();
1474: }
1475: }
1476:
1477: cw.textTag("keywords", s);
1478: }
1479:
1480: if ((cv.getDefaultStyle() != null)
1481: && (cv.getDefaultStyle() != "")) {
1482: cw
1483: .comment("the default style this CoverageInfoDTO can be represented by.\n"
1484: + "at least must contain the \"default\" attribute ");
1485: m = new HashMap();
1486: m.put("default", cv.getDefaultStyle());
1487:
1488: final ArrayList styles = cv.getStyles();
1489:
1490: if (styles.isEmpty()) {
1491: cw.attrTag("styles", m);
1492: } else {
1493: cw.openTag("styles", m);
1494:
1495: Iterator s_IT = styles.iterator();
1496:
1497: while (s_IT.hasNext())
1498: cw.textTag("style", (String) s_IT.next());
1499:
1500: cw.closeTag("styles");
1501: }
1502: }
1503:
1504: if (cv.getEnvelope() != null) {
1505: GeneralEnvelope e = cv.getEnvelope();
1506: m = new HashMap();
1507:
1508: if ((cv.getSrsName() != null)
1509: && (cv.getSrsName() != "")) {
1510: m.put("srsName", cv.getSrsName());
1511: }
1512:
1513: m.put("crs", cv.getCrs().toWKT().replaceAll("\"", "'")
1514: .replaceAll("\r\n", "\n"));
1515:
1516: if (!e.isNull()) {
1517: cw.openTag("envelope", m);
1518: cw.textTag("pos", e.getLowerCorner().getOrdinate(0)
1519: + " " + e.getLowerCorner().getOrdinate(1));
1520: cw.textTag("pos", e.getUpperCorner().getOrdinate(0)
1521: + " " + e.getUpperCorner().getOrdinate(1));
1522: cw.closeTag("envelope");
1523: }
1524: }
1525:
1526: // //
1527: // AlFa: storing the grid-geometry
1528: // //
1529: if (cv.getGrid() != null) {
1530: GridGeometry g = cv.getGrid();
1531: MathTransform tx = g.getGridToCRS();
1532:
1533: InternationalString[] dimNames = cv.getDimensionNames();
1534: m = new HashMap();
1535:
1536: m.put("dimension", new Integer(g.getGridRange()
1537: .getDimension()));
1538:
1539: String lowers = "";
1540: String upers = "";
1541:
1542: for (int r = 0; r < g.getGridRange().getDimension(); r++) {
1543: lowers += (g.getGridRange().getLower(r) + " ");
1544: upers += (g.getGridRange().getUpper(r) + " ");
1545: }
1546:
1547: cw.openTag("grid", m);
1548: cw.textTag("low", lowers);
1549: cw.textTag("high", upers);
1550:
1551: if (dimNames != null) {
1552: for (int dn = 0; dn < dimNames.length; dn++)
1553: cw.textTag("axisName", dimNames[dn].toString());
1554: }
1555:
1556: // //
1557: // AlFa: storing geo-transform
1558: // //
1559: if (tx instanceof AffineTransform) {
1560: AffineTransform aTX = (AffineTransform) tx;
1561: cw.openTag("geoTransform");
1562: cw.textTag("scaleX", String
1563: .valueOf(aTX.getScaleX()));
1564: cw.textTag("scaleY", String
1565: .valueOf(aTX.getScaleY()));
1566: cw.textTag("shearX", String
1567: .valueOf(aTX.getShearX()));
1568: cw.textTag("shearY", String
1569: .valueOf(aTX.getShearY()));
1570: cw.textTag("translateX", String.valueOf(aTX
1571: .getTranslateX()));
1572: cw.textTag("translateY", String.valueOf(aTX
1573: .getTranslateY()));
1574: cw.closeTag("geoTransform");
1575: }
1576:
1577: cw.closeTag("grid");
1578: }
1579:
1580: if (cv.getDimensions() != null) {
1581: CoverageDimension[] dims = cv.getDimensions();
1582:
1583: for (int d = 0; d < dims.length; d++) {
1584: Double[] nulls = dims[d].getNullValues();
1585: cw.openTag("CoverageDimension");
1586: cw.textTag("name", dims[d].getName());
1587: cw.textTag("description", dims[d].getDescription());
1588:
1589: if (dims[d].getRange() != null) {
1590: cw.openTag("interval");
1591: cw.textTag("min", Double.toString(dims[d]
1592: .getRange().getMinimum(true)));
1593: cw.textTag("max", Double.toString(dims[d]
1594: .getRange().getMaximum(true)));
1595: cw.closeTag("interval");
1596: }
1597:
1598: if (nulls != null) {
1599: cw.openTag("nullValues");
1600:
1601: for (int n = 0; n < nulls.length; n++) {
1602: cw.textTag("value", nulls[n].toString());
1603: }
1604:
1605: cw.closeTag("nullValues");
1606: }
1607:
1608: cw.closeTag("CoverageDimension");
1609: }
1610: }
1611:
1612: cw.openTag("supportedCRSs");
1613:
1614: if ((cv.getRequestCRSs() != null)
1615: && (cv.getRequestCRSs().size() != 0)) {
1616: String s = "";
1617: Iterator i = cv.getRequestCRSs().iterator();
1618:
1619: if (i.hasNext()) {
1620: s = i.next().toString();
1621:
1622: while (i.hasNext()) {
1623: s = s + "," + i.next().toString();
1624: }
1625: }
1626:
1627: cw.textTag("requestCRSs", s);
1628: }
1629:
1630: if ((cv.getResponseCRSs() != null)
1631: && (cv.getResponseCRSs().size() != 0)) {
1632: String s = "";
1633: Iterator i = cv.getResponseCRSs().iterator();
1634:
1635: if (i.hasNext()) {
1636: s = i.next().toString();
1637:
1638: while (i.hasNext()) {
1639: s = s + "," + i.next().toString();
1640: }
1641: }
1642:
1643: cw.textTag("responseCRSs", s);
1644: }
1645:
1646: cw.closeTag("supportedCRSs");
1647:
1648: m = new HashMap();
1649:
1650: if ((cv.getNativeFormat() != null)
1651: && (cv.getNativeFormat() != "")) {
1652: m.put("nativeFormat", cv.getNativeFormat());
1653: }
1654:
1655: cw.openTag("supportedFormats", m);
1656:
1657: if ((cv.getSupportedFormats() != null)
1658: && (cv.getSupportedFormats().size() != 0)) {
1659: String s = "";
1660: Iterator i = cv.getSupportedFormats().iterator();
1661:
1662: if (i.hasNext()) {
1663: s = i.next().toString();
1664:
1665: while (i.hasNext()) {
1666: s = s + "," + i.next().toString();
1667: }
1668: }
1669:
1670: cw.textTag("formats", s);
1671: }
1672:
1673: cw.closeTag("supportedFormats");
1674:
1675: m = new HashMap();
1676:
1677: if ((cv.getDefaultInterpolationMethod() != null)
1678: && (cv.getDefaultInterpolationMethod() != "")) {
1679: m.put("default", cv.getDefaultInterpolationMethod());
1680: }
1681:
1682: cw.openTag("supportedInterpolations", m);
1683:
1684: if ((cv.getInterpolationMethods() != null)
1685: && (cv.getInterpolationMethods().size() != 0)) {
1686: String s = "";
1687: Iterator i = cv.getInterpolationMethods().iterator();
1688:
1689: if (i.hasNext()) {
1690: s = i.next().toString();
1691:
1692: while (i.hasNext()) {
1693: s = s + "," + i.next().toString();
1694: }
1695: }
1696:
1697: cw.textTag("interpolationMethods", s);
1698: }
1699:
1700: cw.closeTag("supportedInterpolations");
1701:
1702: // ///////////////////////////////////////////////////////////////////////
1703: //
1704: // STORING READ PARAMETERS
1705: //
1706: // ///////////////////////////////////////////////////////////////////////
1707: if ((cv.getParameters() != null)
1708: && (cv.getParameters().size() != 0)) {
1709: cw.openTag("parameters");
1710:
1711: final Iterator i = cv.getParameters().keySet()
1712: .iterator();
1713: final HashMap temp = new HashMap();
1714:
1715: while (i.hasNext()) {
1716: String key = (String) i.next();
1717:
1718: if ("values_palette".equalsIgnoreCase(key)) {
1719: String text = "";
1720: Object palVal = cv.getParameters().get(key);
1721:
1722: if (palVal instanceof Color[]) {
1723: for (int col = 0; col < ((Color[]) palVal).length; col++) {
1724: String colString = "#"
1725: + ((Integer
1726: .toHexString(
1727: ((Color) ((Color[]) palVal)[col])
1728: .getRed())
1729: .length() > 1) ? Integer
1730: .toHexString(((Color) ((Color[]) palVal)[col])
1731: .getRed())
1732: : ("0" + Integer
1733: .toHexString(((Color) ((Color[]) palVal)[col])
1734: .getRed())))
1735: + ((Integer
1736: .toHexString(
1737: ((Color) ((Color[]) palVal)[col])
1738: .getGreen())
1739: .length() > 1) ? Integer
1740: .toHexString(((Color) ((Color[]) palVal)[col])
1741: .getGreen())
1742: : ("0" + Integer
1743: .toHexString(((Color) ((Color[]) palVal)[col])
1744: .getGreen())))
1745: + ((Integer
1746: .toHexString(
1747: ((Color) ((Color[]) palVal)[col])
1748: .getBlue())
1749: .length() > 1) ? Integer
1750: .toHexString(((Color) ((Color[]) palVal)[col])
1751: .getBlue())
1752: : ("0" + Integer
1753: .toHexString(((Color) ((Color[]) palVal)[col])
1754: .getBlue())));
1755: text += (((col > 0) ? ";" : "") + colString);
1756: }
1757: } else if (palVal instanceof String) {
1758: text = (String) palVal;
1759: }
1760:
1761: temp.put("name", key);
1762: temp.put("value", text);
1763: } else {
1764: temp.put("name", key);
1765: temp.put("value", cv.getParameters().get(key)
1766: .toString().replaceAll("\"", "'"));
1767: }
1768:
1769: cw.attrTag("parameter", temp);
1770: }
1771:
1772: cw.closeTag("parameters");
1773: }
1774:
1775: cw.closeTag("coverage");
1776: fw.close();
1777: } catch (IOException e) {
1778: throw new ConfigurationException(e);
1779: }
1780: }
1781:
1782: /**
1783: * WriterUtils purpose.
1784: *
1785: * <p>
1786: * This is a static class which is used by XMLConfigWriter for File IO
1787: * validation tests.
1788: * </p>
1789: *
1790: * <p></p>
1791: *
1792: * @author dzwiers, Refractions Research, Inc.
1793: * @version $Id: XMLConfigWriter.java 8482 2008-02-29 04:59:42Z arneke $
1794: */
1795: public static class WriterUtils {
1796: /** Used internally to create log information to detect errors. */
1797: private static final Logger LOGGER = Logger
1798: .getLogger("org.vfny.geoserver.global");
1799:
1800: /**
1801: * WriterUtils constructor.
1802: *
1803: * <p>
1804: * Static class, should never be used.
1805: * </p>
1806: */
1807: private WriterUtils() {
1808: }
1809:
1810: /**
1811: * initFile purpose.
1812: *
1813: * <p>
1814: * Checks to ensure the handle exists. If the handle is a directory and not
1815: * created, it is created
1816: * </p>
1817: *
1818: * @param f the File handle
1819: * @param isDir true when the handle is intended to be a directory.
1820: *
1821: * @return The file passed in.
1822: *
1823: * @throws ConfigurationException When an IO error occurs or the handle is
1824: * invalid.
1825: */
1826: public static File initFile(File f, boolean isDir)
1827: throws ConfigurationException {
1828: if (!f.exists()) {
1829: if (LOGGER.isLoggable(Level.FINER)) {
1830: LOGGER.finer(new StringBuffer("Creating File: ")
1831: .append(f.toString()).toString());
1832: }
1833:
1834: if (isDir) {
1835: if (!f.mkdir()) {
1836: throw new ConfigurationException(
1837: "Path specified does not have a valid file.\n"
1838: + f + "\n\n");
1839: }
1840: } else {
1841: try {
1842: if (LOGGER.isLoggable(Level.SEVERE)) {
1843: LOGGER.severe(new StringBuffer(
1844: "Attempting to create file:")
1845: .append(f.getAbsolutePath())
1846: .toString());
1847: }
1848:
1849: if (!f.createNewFile()) {
1850: throw new ConfigurationException(
1851: "Path specified does not have a valid file.\n"
1852: + f + "\n\n");
1853: }
1854: } catch (IOException e) {
1855: throw new ConfigurationException(e);
1856: }
1857: }
1858: }
1859:
1860: if (isDir && !f.isDirectory()) {
1861: throw new ConfigurationException(
1862: "Path specified does not have a valid file.\n"
1863: + f + "\n\n");
1864: }
1865:
1866: if (!isDir && !f.isFile()) {
1867: throw new ConfigurationException(
1868: "Path specified does not have a valid file.\n"
1869: + f + "\n\n");
1870: }
1871:
1872: if (LOGGER.isLoggable(Level.FINER)) {
1873: LOGGER.finer(new StringBuffer("File is valid: ")
1874: .append(f).toString());
1875: }
1876:
1877: return f;
1878: }
1879:
1880: /**
1881: * initFile purpose.
1882: *
1883: * <p>
1884: * Checks to ensure the handle exists and can be writen to. If the handle
1885: * is a directory and not created, it is created
1886: * </p>
1887: *
1888: * @param f the File handle
1889: * @param isDir true when the handle is intended to be a directory.
1890: *
1891: * @return The file passed in.
1892: *
1893: * @throws ConfigurationException When an IO error occurs or the handle is
1894: * invalid.
1895: */
1896: public static File initWriteFile(File f, boolean isDir)
1897: throws ConfigurationException {
1898: initFile(f, isDir);
1899:
1900: if (!f.canWrite()) {
1901: throw new ConfigurationException(
1902: "Cannot Write to file: " + f.toString());
1903: }
1904:
1905: return f;
1906: }
1907: }
1908: }
|