/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, availible at the root * application directory. */ package org.vfny.geoserver.global.xml; import java.awt.geom.AffineTransform; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.transform.TransformerException; import org.apache.commons.io.FileUtils; import org.geotools.filter.FilterTransformer; import org.geotools.geometry.GeneralEnvelope; import org.geotools.referencing.CRS; import org.geotools.util.logging.Logging; import org.opengis.coverage.grid.GridGeometry; import org.opengis.referencing.operation.MathTransform; import org.opengis.util.InternationalString; import org.vfny.geoserver.global.ConfigurationException; import org.vfny.geoserver.global.CoverageDimension; import org.vfny.geoserver.global.MetaDataLink; import org.vfny.geoserver.global.dto.AttributeTypeInfoDTO; import org.vfny.geoserver.global.dto.ContactDTO; import org.vfny.geoserver.global.dto.CoverageInfoDTO; import org.vfny.geoserver.global.dto.CoverageStoreInfoDTO; import org.vfny.geoserver.global.dto.DataDTO; import org.vfny.geoserver.global.dto.DataStoreInfoDTO; import org.vfny.geoserver.global.dto.FeatureTypeInfoDTO; import org.vfny.geoserver.global.dto.GeoServerDTO; import org.vfny.geoserver.global.dto.NameSpaceInfoDTO; import org.vfny.geoserver.global.dto.ServiceDTO; import org.vfny.geoserver.global.dto.StyleDTO; import org.vfny.geoserver.global.dto.WCSDTO; import org.vfny.geoserver.global.dto.WFSDTO; import org.vfny.geoserver.global.dto.WMSDTO; import com.vividsolutions.jts.geom.Envelope; /** * XMLConfigWriter purpose. * * <p> * This class is intended to store a configuration to be written and complete * the output to XML. * </p> * * <p> * </p> * * @author dzwiers, Refractions Research, Inc. * @version $Id$ */ public class XMLConfigWriter { /** Used internally to create log information to detect errors. */ private static final Logger LOGGER = org.geotools.util.logging.Logging .getLogger("org.vfny.geoserver.global"); /** * XMLConfigWriter constructor. * * <p> * Should never be called. * </p> */ private XMLConfigWriter() { } public static void store(DataDTO data, File root) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("In method store DataDTO"); } if (data == null) { throw new ConfigurationException("DataDTO is null: cannot write."); } WriterUtils.initFile(root, true); // boolean inDataDir = GeoserverDataDirectory.isTrueDataDir(); // We're just checking if it's actually a data_dir, not trying to // to do backwards compatibility. So if an old data_dir is made in // the old way, on save it'll come to the new way. File fileDir = root; // ? root : new File(root, "WEB-INF/"); File configDir = WriterUtils.initFile(fileDir, true); File catalogFile = WriterUtils.initWriteFile(new File(configDir, "catalog.xml"), false); try { Writer fw = new OutputStreamWriter(new FileOutputStream(catalogFile), getDefaultEncoding()); storeCatalog(new WriterHelper(fw), data); fw.close(); } catch (IOException e) { throw new ConfigurationException("Store" + root, e); } File dataDir; // if (!inDataDir) { // dataDir = WriterUtils.initFile(new File(root, "data/"), true); // } else { dataDir = root; // } File featureTypeDir = WriterUtils.initFile(new File(dataDir, "featureTypes/"), true); storeFeatures(featureTypeDir, data); File coverageDir = WriterUtils.initFile(new File(dataDir, "coverages/"), true); storeCoverages(coverageDir, data); } /** * Returns the default encoding for configuration files. For the moment we * default to UTF8, but we may want to make this user configurable (UTF-16 * may be needed?) * * @return */ private static String getDefaultEncoding() { return "UTF-8"; } public static void store(WCSDTO wcs, WMSDTO wms, WFSDTO wfs, GeoServerDTO geoServer, File root) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("In method store WCSDTO,WMSDTO,WFSDTO, GeoServerDTO"); } if (geoServer == null) { throw new ConfigurationException( "null parameter in store(WCSDTO,WMSDTO,WFSDTO, GeoServerDTO): cannot write."); } WriterUtils.initFile(root, true); // boolean inDataDir = GeoserverDataDirectory.isTrueDataDir(); // We're just checking if it's actually a data_dir, not trying to // to do backwards compatibility. So if an old data_dir is made in // the old way, on save it'll come to the new way. File fileDir = root; // inDataDir ? root : new File(root, // "WEB-INF/"); File configDir = WriterUtils.initFile(fileDir, true); File configFile = WriterUtils.initWriteFile(new File(configDir, "services.xml"), false); try { Writer fw = new OutputStreamWriter(new FileOutputStream(configFile), getDefaultEncoding()); storeServices(new WriterHelper(fw), wcs, wms, wfs, geoServer); fw.close(); } catch (IOException e) { throw new ConfigurationException("Store" + root, e); } } public synchronized static void store(WCSDTO wcs, WMSDTO wms, WFSDTO wfs, GeoServerDTO geoServer, DataDTO data, File root) throws ConfigurationException { store(wcs, wms, wfs, geoServer, root); store(data, root); } /** * storeServices purpose. * * <p> * Writes the services.xml file from the model in memory. * </p> * * @param cw * The Configuration Writer * @param wms * DOCUMENT ME! * @param wfs * DOCUMENT ME! * @param geoServer * DOCUMENT ME! * * @throws ConfigurationException * When an IO exception occurs. */ protected static void storeServices(WriterHelper cw, WCSDTO wcs, WMSDTO wms, WFSDTO wfs, GeoServerDTO geoServer) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("In method storeServices"); } cw.writeln("<?config.xml version=\"1.0\" encoding=\"UTF-8\"?>"); cw.comment("Service level configuration"); cw.openTag("serverConfiguration"); GeoServerDTO g = geoServer; if (g != null) { cw.openTag("global"); if (g.getLog4jConfigFile() != null) { cw.textTag("log4jConfigFile", g.getLog4jConfigFile()); } cw.valueTag("suppressStdOutLogging", g.getSuppressStdOutLogging() + ""); if (g.getLogLocation() != null) { cw.textTag("logLocation", g.getLogLocation()); } cw.valueTag("JaiMemoryCapacity", "" + g.getJaiMemoryCapacity()); cw.valueTag("JaiMemoryThreshold", "" + g.getJaiMemoryThreshold()); cw.valueTag("JaiTileThreads", "" + g.getJaiTileThreads()); cw.valueTag("JaiTilePriority", "" + g.getJaiTilePriority()); cw.valueTag("JaiRecycling", "" + g.getJaiRecycling()); cw.valueTag("ImageIOCache", "" + g.getImageIOCache()); cw.valueTag("JaiJPEGNative", "" + g.getJaiJPEGNative()); cw.valueTag("JaiPNGNative", "" + g.getJaiPNGNative()); cw.valueTag("JaiMosaicNative", "" + g.getJaiMosaicNative()); /* * if(g.getBaseUrl()!=null && g.getBaseUrl()!=""){ cw.comment("The * base URL where this servlet will run. If running locally\n"+ * "then http://localhost:8080 (or whatever port you're running * on)\n"+ "should work. If you are serving to the world then this * must be\n"+ "the location where the geoserver servlets appear"); * cw.textTag("URL",g.getBaseUrl()); } */ cw.comment("Sets the max number of Features returned by GetFeature"); cw.valueTag("maxFeatures", "" + g.getMaxFeatures()); cw.comment("Whether newlines and indents should be returned in \n" + "XML responses. Default is false"); cw.valueTag("verbose", "" + g.isVerbose()); cw.comment("Whether the Service Exceptions returned to clients should contain\n" + "full java stack traces (useful for debugging). "); cw.valueTag("verboseExceptions", "" + g.isVerboseExceptions()); cw.comment("Sets the max number of decimal places past the zero returned in\n" + "a GetFeature response. Default is 4"); cw.valueTag("numDecimals", "" + g.getNumDecimals()); if (g.getCharSet() != null) { cw .comment("Sets the global character set. This could use some more testing\n" + "from international users, but what it does is sets the encoding\n" + "globally for all postgis database connections (the charset tag\n" + "in FeatureTypeConfig), as well as specifying the encoding in the return\n" + "config.xml header and mime type. The default is UTF-8. Also be warned\n" + "that GeoServer does not check if the CharSet is valid before\n" + "attempting to use it, so it will fail miserably if a bad charset\n" + "is used."); cw.valueTag("charSet", g.getCharSet().toString()); } if ((g.getSchemaBaseUrl() != null) && (g.getSchemaBaseUrl() != "")) { cw.comment("Define a base url for the location of the wfs schemas.\n" + "By default GeoServer loads and references its own at\n" + "<URL>/data/capabilities. Uncomment to enable. The\n" + "standalone Tomcat server needs SchemaBaseUrl defined\n" + "for validation."); cw.textTag("SchemaBaseUrl", g.getSchemaBaseUrl()); } if ((g.getProxyBaseUrl() != null) && (g.getSchemaBaseUrl() != "")) { cw.comment("Define a base url for the geoserver application.\n" + "By default GeoServer uses the local one, but it may " + "be wrong if you're using a reverse proxy in front of Geoserver"); cw.textTag("ProxyBaseUrl", g.getProxyBaseUrl()); } // removed, the user is now stored in the users.properties file // if ((g.getAdminUserName() != null) && (g.getAdminUserName() != // "")) { // cw.comment("Defines the user name of the administrator for log // in\n" // + "to the web based administration tool."); // cw.textTag("adminUserName", g.getAdminUserName()); // } // // if ((g.getAdminPassword() != null) && (g.getAdminPassword() != // "")) { // cw.comment("Defines the password of the administrator for log // in\n" // + "to the web based administration tool."); // cw.textTag("adminPassword", g.getAdminPassword()); // } if (g.getContact() != null) { storeContact(g.getContact(), cw); } //if ((g.getTileCache() != null) && !"".equals(g.getTileCache().trim())) { // cw.comment("Defines hte location of a tile cache (full url or relative path)"); // cw.textTag("tileCache", g.getTileCache()); //} cw.comment("Stores the current updateSequence"); cw.textTag("updateSequence", g.getUpdateSequence() + ""); cw.closeTag("global"); } if (!((wcs == null) && (wfs == null) && (wms == null))) { cw.openTag("services"); if (wcs != null) { storeService(wcs, cw); } if (wfs != null) { storeService(wfs, cw); } if (wms != null) { storeService(wms, cw); } // Z39.50 is not used in the current system. cw.closeTag("services"); } cw.closeTag("serverConfiguration"); } /** * storeContact purpose. * * <p> * Writes a contact into the WriterUtils provided from the ContactConfig * provided. * </p> * * @param c * The ContactConfig to write. * @param cw * The Configuration Writer * * @throws ConfigurationException * When an IO exception occurs. */ protected static void storeContact(ContactDTO c, WriterHelper cw) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("In method storeContact"); } if ((c != null) && !c.equals(new ContactDTO())) { cw.openTag("ContactInformation"); cw.openTag("ContactPersonPrimary"); cw.textTag("ContactPerson", c.getContactPerson()); cw.textTag("ContactOrganization", c.getContactOrganization()); cw.closeTag("ContactPersonPrimary"); cw.textTag("ContactPosition", c.getContactPosition()); cw.openTag("ContactAddress"); cw.textTag("AddressType", c.getAddressType()); cw.textTag("Address", c.getAddress()); cw.textTag("City", c.getAddressCity()); cw.textTag("StateOrProvince", c.getAddressState()); cw.textTag("PostCode", c.getAddressPostalCode()); cw.textTag("Country", c.getAddressCountry()); cw.closeTag("ContactAddress"); cw.textTag("ContactVoiceTelephone", c.getContactVoice()); cw.textTag("ContactFacsimileTelephone", c.getContactFacsimile()); cw.textTag("ContactElectronicMailAddress", c.getContactEmail()); cw.textTag("ContactOnlineResource", c.getOnlineResource()); cw.closeTag("ContactInformation"); } } /** * storeService purpose. * * <p> * Writes a service into the WriterUtils provided from the WFS or WMS object * provided. * </p> * * @param obj * either a WFS or WMS object. * @param cw * The Configuration Writer * * @throws ConfigurationException * When an IO exception occurs or the object provided is not of * the correct type. */ protected static void storeService(Object obj, WriterHelper cw) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("In method storeService"); } ServiceDTO s = null; String u = null; String t = ""; boolean fBounds = false; boolean srsXmlStyle = false; int serviceLevel = 0; String svgRenderer = null; Map baseMapLayers = null; Map baseMapStyles = null; Map baseMapEnvelopes = null; boolean svgAntiAlias = false; boolean globalWatermarking = false; String globalWatermarkingURL = null; int watermarkTransparency = 0; int watermarkPosition = 8; String allowInterpolation = null; boolean citeConformanceHacks = false; if (obj instanceof WCSDTO) { WCSDTO w = (WCSDTO) obj; s = w.getService(); t = "WCS"; // citeConformanceHacks = w.getCiteConformanceHacks(); } else if (obj instanceof WFSDTO) { WFSDTO w = (WFSDTO) obj; s = w.getService(); t = "WFS"; fBounds = w.isFeatureBounding(); srsXmlStyle = w.isSrsXmlStyle(); serviceLevel = w.getServiceLevel(); citeConformanceHacks = w.getCiteConformanceHacks(); } else if (obj instanceof WMSDTO) { WMSDTO w = (WMSDTO) obj; s = w.getService(); t = "WMS"; svgRenderer = w.getSvgRenderer(); svgAntiAlias = w.getSvgAntiAlias(); globalWatermarking = w.getGlobalWatermarking(); globalWatermarkingURL = w.getGlobalWatermarkingURL(); watermarkTransparency = w.getWatermarkTransparency(); watermarkPosition = w.getWatermarkPosition(); allowInterpolation = w.getAllowInterpolation(); baseMapLayers = w.getBaseMapLayers(); baseMapStyles = w.getBaseMapStyles(); baseMapEnvelopes = w.getBaseMapEnvelopes(); } else { throw new ConfigurationException("Invalid object: not WMS or WFS or WCS"); } Map atrs = new HashMap(); atrs.put("type", t); atrs.put("enabled", s.isEnabled() + ""); cw.openTag("service", atrs); cw.comment("ServiceDTO elements, needed for the capabilities document\n" + "Title and OnlineResource are the two required"); if ((s.getName() != null) && (s.getName() != "")) { cw.textTag("name", s.getName()); } if ((s.getTitle() != null) && (s.getTitle() != "")) { cw.textTag("title", s.getTitle()); } if ((s.getAbstract() != null) && (s.getAbstract() != "")) { cw.textTag("abstract", s.getAbstract()); } if (s.getMetadataLink() != null) { MetaDataLink ml = s.getMetadataLink(); Map mlAttr = new HashMap(); mlAttr.put("about", ml.getAbout()); mlAttr.put("type", ml.getType()); mlAttr.put("metadataType", ml.getMetadataType()); cw.textTag("metadataLink", mlAttr, ml.getContent()); } if (!s.getKeywords().isEmpty()) { cw.openTag("keywords"); for (int i = 0; i < s.getKeywords().size(); i++) { String str = s.getKeywords().get(i).toString(); cw.textTag("keyword", str.replaceAll("\\r", "")); } cw.closeTag("keywords"); } if (s.getOnlineResource() != null) { cw.textTag("onlineResource", s.getOnlineResource().toString()); } if ((s.getFees() != null) && (s.getFees() != "")) { cw.textTag("fees", s.getFees()); } if ((s.getAccessConstraints() != null) && (s.getAccessConstraints() != "")) { cw.textTag("accessConstraints", s.getAccessConstraints()); } if (fBounds) { cw.valueTag("featureBounding", fBounds + ""); } // if (srsXmlStyle) { cw.valueTag("srsXmlStyle", srsXmlStyle + ""); // } if (serviceLevel != 0) { cw.valueTag("serviceLevel", serviceLevel + ""); } if (obj instanceof WFSDTO) // DJB: this method (storeService) doesnt // separate WFS and WMS very well! { cw.textTag("citeConformanceHacks", citeConformanceHacks + ""); } if ((s.getMaintainer() != null) && (s.getMaintainer() != "")) { cw.textTag("maintainer", s.getMaintainer()); } if (svgRenderer != null) { cw.textTag("svgRenderer", svgRenderer); } if ((baseMapLayers != null) && (baseMapStyles != null) && (baseMapEnvelopes != null)) { cw.openTag("BaseMapGroups"); // for each title/layer combo, write it out String[] titles = (String[]) baseMapLayers.keySet().toArray(new String[0]); for (int i = 0; i < titles.length; i++) { HashMap titleMap = new HashMap(); titleMap.put("baseMapTitle", titles[i]); cw.openTag("BaseMapGroup", titleMap); cw.textTag("baseMapLayers", (String) baseMapLayers.get(titles[i])); cw.textTag("baseMapStyles", (String) baseMapStyles.get(titles[i])); GeneralEnvelope e = (GeneralEnvelope) baseMapEnvelopes.get(titles[i]); Map m = new HashMap(); try { m.put( "srsName", "EPSG:" + CRS.lookupEpsgCode(e.getCoordinateReferenceSystem(),true)); } catch (Exception ex) { m.put("srsName", e.getCoordinateReferenceSystem().getIdentifiers().toArray()[0].toString()); } if (!e.isNull()) { cw.openTag("baseMapEnvelope", m); cw.textTag("pos", e.getLowerCorner().getOrdinate(0) + " " + e.getLowerCorner().getOrdinate(1)); cw.textTag("pos", e.getUpperCorner().getOrdinate(0) + " " + e.getUpperCorner().getOrdinate(1)); cw.closeTag("baseMapEnvelope"); } cw.closeTag("BaseMapGroup"); } cw.closeTag("BaseMapGroups"); } if (obj instanceof WMSDTO) { Set limitedCrsListForCapabilities = ((WMSDTO) obj).getCapabilitiesCrs(); StringBuffer sb = new StringBuffer(); for (Iterator it = limitedCrsListForCapabilities.iterator(); it.hasNext();) { sb.append(it.next()); if (it.hasNext()) { sb.append(", "); } } cw.comment("List of EPSG codes used to limit the number of SRS elements\n" + "shown in the WMS GetCapabilities document"); cw.textTag("capabilitiesCrsList", sb.toString()); cw.textTag("svgAntiAlias", svgAntiAlias + ""); cw.textTag("globalWatermarking", globalWatermarking + ""); if (globalWatermarkingURL != null) { cw.textTag("globalWatermarkingURL", globalWatermarkingURL); } cw.textTag("globalWatermarkingTransparency", watermarkTransparency + ""); cw.textTag("globalWatermarkingPosition", watermarkPosition + ""); if (allowInterpolation != null) { cw.textTag("allowInterpolation", allowInterpolation); } } if ((s.getStrategy() != null) && !"".equals(s.getStrategy())) { cw.textTag("serviceStrategy", s.getStrategy()); } if (s.getPartialBufferSize() != 0) { cw.textTag("partialBufferSize", s.getPartialBufferSize() + ""); } cw.closeTag("service"); } /** * storeCatalog purpose. * * <p> * Writes a catalog into the WriterUtils provided from Data provided in * memory. * </p> * * @param cw * The Configuration Writer * @param data * DOCUMENT ME! * * @throws ConfigurationException * When an IO exception occurs. */ protected static void storeCatalog(WriterHelper cw, DataDTO data) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("In method storeCatalog"); } cw.writeln("<?config.xml version=\"1.0\" encoding=\"UTF-8\"?>"); cw.openTag("catalog"); // DJB: this used to not put in a datastores tag if there were none // defined. // this caused the loader to blow up. I changed it so it puts an empty // <datastore> here! cw.openTag("datastores"); cw.comment("a datastore configuration element serves as a common data source connection\n" + "parameters repository for all featuretypes it holds."); Iterator i = data.getDataStores().keySet().iterator(); while (i.hasNext()) { String s = (String) i.next(); DataStoreInfoDTO ds = (DataStoreInfoDTO) data.getDataStores().get(s); if (ds != null) { storeDataStore(cw, ds); } } cw.closeTag("datastores"); // DJB: since datastore screws up if the tag is missing, I'm fixing it // here too cw.openTag("formats"); cw.comment("a format configuration element serves as a common data source\n" + "parameters repository for all coverages it holds."); i = data.getFormats().keySet().iterator(); while (i.hasNext()) { String s = (String) i.next(); CoverageStoreInfoDTO df = (CoverageStoreInfoDTO) data.getFormats().get(s); if (df != null) { storeFormat(cw, df); } } cw.closeTag("formats"); cw.comment("Defines namespaces to be used by the datastores."); cw.openTag("namespaces"); i = data.getNameSpaces().keySet().iterator(); while (i.hasNext()) { String s = (String) i.next(); NameSpaceInfoDTO ns = (NameSpaceInfoDTO) data.getNameSpaces().get(s); if (ns != null) { storeNameSpace(cw, ns); } } cw.closeTag("namespaces"); // DJB: since datastore screws up if the tag is missing, I'm fixing it // here too cw.openTag("styles"); cw.comment("Defines the style ids and file name to be used by the wms."); i = data.getStyles().keySet().iterator(); while (i.hasNext()) { String s = (String) i.next(); StyleDTO st = (StyleDTO) data.getStyles().get(s); if (st != null) { storeStyle(cw, st); } } cw.closeTag("styles"); cw.closeTag("catalog"); } /** * storeDataStore purpose. * * <p> * Writes a DataStoreInfo into the WriterUtils provided. * </p> * * @param cw * The Configuration Writer * @param ds * The Datastore. * * @throws ConfigurationException * When an IO exception occurs. */ protected static void storeDataStore(WriterHelper cw, DataStoreInfoDTO ds) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("In method storeDataStore"); } Map temp = new HashMap(); if (ds.getId() != null) { temp.put("id", ds.getId()); } temp.put("enabled", ds.isEnabled() + ""); if (ds.getNameSpaceId() != null) { temp.put("namespace", ds.getNameSpaceId()); } cw.openTag("datastore", temp); if ((ds.getAbstract() != null) && (ds.getAbstract() != "")) { cw.textTag("abstract", ds.getAbstract()); } if ((ds.getTitle() != null) && (ds.getTitle() != "")) { cw.textTag("title", ds.getTitle()); } if (ds.getConnectionParams().size() != 0) { cw.openTag("connectionParams"); Iterator i = ds.getConnectionParams().keySet().iterator(); temp = new HashMap(); while (i.hasNext()) { String key = (String) i.next(); temp.put("name", key); temp.put("value", ds.getConnectionParams().get(key).toString()); cw.attrTag("parameter", temp); } cw.closeTag("connectionParams"); } cw.closeTag("datastore"); } /** * storeFormat purpose. * * <p> * Writes a CoverageStoreInfo into the WriterUtils provided. * </p> * * @param cw * The Configuration Writer * @param store * The Format. * * @throws ConfigurationException * When an IO exception occurs. */ protected static void storeFormat(WriterHelper cw, CoverageStoreInfoDTO df) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("In method storeFormat"); } Map temp = new HashMap(); if (df.getId() != null) { temp.put("id", df.getId()); } temp.put("enabled", df.isEnabled() + ""); if (df.getNameSpaceId() != null) { temp.put("namespace", df.getNameSpaceId()); } cw.openTag("format", temp); if ((df.getAbstract() != null) && (df.getAbstract() != "")) { cw.textTag("description", df.getAbstract()); } if ((df.getTitle() != null) && (df.getTitle() != "")) { cw.textTag("title", df.getTitle()); } if ((df.getType() != null) && (df.getType() != "")) { cw.textTag("type", df.getType()); } if ((df.getUrl() != null) && (df.getUrl() != "")) { cw.textTag("url", df.getUrl()); } cw.closeTag("format"); } /** * storeNameSpace purpose. * * <p> * Writes a NameSpaceInfoDTO into the WriterUtils provided. * </p> * * @param cw * The Configuration Writer * @param ns * The NameSpaceInfo. * * @throws ConfigurationException * When an IO exception occurs. */ protected static void storeNameSpace(WriterHelper cw, NameSpaceInfoDTO ns) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("In method storeNameSpace"); } Map attr = new HashMap(); if ((ns.getUri() != null) && (ns.getUri() != "")) { attr.put("uri", ns.getUri()); } if ((ns.getPrefix() != null) && (ns.getPrefix() != "")) { attr.put("prefix", ns.getPrefix()); } if (ns.isDefault()) { attr.put("default", "true"); } if (attr.size() != 0) { cw.attrTag("namespace", attr); } } /** * storeStyle purpose. * * <p> * Writes a StyleDTO into the WriterUtils provided. * </p> * * @param cw * The Configuration Writer * @param s * The StyleDTO. * * @throws ConfigurationException * When an IO exception occurs. */ protected static void storeStyle(WriterHelper cw, StyleDTO s) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer(new StringBuffer("In method storeStyle: ").append(s).toString()); } Map attr = new HashMap(); if ((s.getId() != null) && (s.getId() != "")) { attr.put("id", s.getId()); } if (s.getFilename() != null) { attr.put("filename", s.getFilename().getName()); } if (s.isDefault()) { attr.put("default", "true"); } if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer(new StringBuffer("storing style ").append(attr).toString()); } if (attr.size() != 0) { cw.attrTag("style", attr); } } /** * storeStyle purpose. * * <p> * Sets up writing FeatureTypes into their Directories. * </p> * * @param dir * The FeatureTypes directory * @param data * DOCUMENT ME! * * @throws ConfigurationException * When an IO exception occurs. * * @see storeFeature(FeatureTypeInfo,File) */ protected static void storeFeatures(File dir, DataDTO data) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("In method storeFeatures"); } // write them Iterator i = data.getFeaturesTypes().keySet().iterator(); while (i.hasNext()) { String s = (String) i.next(); FeatureTypeInfoDTO ft = (FeatureTypeInfoDTO) data.getFeaturesTypes().get(s); if (ft != null) { String ftDirName = featureTypeDirectoryName(ft); try { // encode the file name (this is to catch colons in FT // names) ftDirName = URLEncoder.encode(ftDirName, getDefaultEncoding()); if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer(new StringBuffer("Writing encoded URL: ").append(ftDirName) .toString()); } } catch (UnsupportedEncodingException e1) { throw new ConfigurationException(e1); } File dir2 = WriterUtils.initWriteFile(new File(dir, ftDirName), true); storeFeature(ft, dir2); if (ft.getSchemaAttributes() != null) { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer(new StringBuffer(ft.getKey()) .append(" writing schema.xml w/ ").append( ft.getSchemaAttributes().size()).toString()); } storeFeatureSchema(ft, dir2); } } } // delete old ones that are not overwritten // I'm changing this action, as it is directly leading to users not // being able to create their own shapefiles in the web admin tool. // since their shit always gets deleted. The behaviour has now changed // to just getting rid of the geoserver config files, info.xml and // schema.xml and leaving any others. We should revisit this, I // do think getting rid of stale featureTypes is a good thing. For 1.3 // I want to look into directly uploading shapefiles, and perhaps they // would then go in a 'shapefile' directory, next to featureTypes or // or something, so that the featureTypes directory only contains // the info, and schema and those sorts of files. But I do kind of like // being able to access the shapefiles directly from the web app, and // indeed have had thoughts of expanding that, so that users could // always download the full shape for a layer, generated automatically // if it's from another datastore. Though I suppose that is not // mutually exclusive, just a little wasting of space, for shapefiles // would be held twice. // JD: changing this to back up rather than delete File[] fa = dir.listFiles(); for (int j = 0; j < fa.length; j++) { if ( fa[j].getName().startsWith( ".") ) { //ignore it continue; } // find dir name i = data.getFeaturesTypes().values().iterator(); FeatureTypeInfoDTO fti = null; while ((fti == null) && i.hasNext()) { FeatureTypeInfoDTO ft = (FeatureTypeInfoDTO) i.next(); String ftDirName = featureTypeDirectoryName(ft); try { // encode the file name (this is to catch colons in FT // names) ftDirName = URLEncoder.encode(ftDirName, getDefaultEncoding()); if (LOGGER.isLoggable(Level.FINER)) { LOGGER .finer(new StringBuffer("Decoded URL: ").append(ftDirName) .toString()); } } catch (UnsupportedEncodingException e1) { throw new ConfigurationException(e1); } if (ftDirName.equals(fa[j].getName())) { fti = ft; } } if (fti == null) { // delete it File[] files = fa[j].listFiles(); if (files != null) { for (int x = 0; x < files.length; x++) { // hold on to the data, but be sure to get rid of the // geoserver config shit, as these were deleted. if (files[x].getName().equals("info.xml") || files[x].getName().equals("schema.xml")) { // sorry for the hardcodes, I don't remember // if/where // we have these file names. try { WriterUtils.backupFile( files[x], true ); } catch (IOException e) { LOGGER.severe( "Unable to backup: " + files[x].getAbsolutePath() ); } //files[x].delete(); } } } // rename it if its not a backup if ( !fa[j].getName().endsWith( ".bak") ) { try { WriterUtils.backupDirectory( fa[j] ); } catch (IOException e) { LOGGER.severe( "Unable to backup: " + fa[j].getAbsolutePath() ); } } } } } static String featureTypeDirectoryName( FeatureTypeInfoDTO ft ) { String ftDirName = ft.getDirName(); if ( ftDirName == null ) { ftDirName = ft.getDataStoreId() + "_" + (ft.getAlias() != null ? ft.getAlias() : ft.getName()); } return ftDirName; } /** * storeStyle purpose. * * <p> * Writes a FeatureTypes into it's Directory. * </p> * * @param ft * DOCUMENT ME! * @param dir * The particular FeatureTypeInfo directory * * @throws ConfigurationException * When an IO exception occurs. * * @see storeFeatures(File) */ protected static void storeFeature(FeatureTypeInfoDTO ft, File dir) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("In method storeFeature"); } File ftInfo = new File(dir, "info.xml"); //back up file if it already exists if ( ftInfo.exists() ) { try { WriterUtils.backupFile( ftInfo, true ); } catch (IOException e) { LOGGER.severe( "Unable to backup: " + ftInfo.getAbsolutePath() ); } } File f = WriterUtils.initWriteFile(ftInfo, false); try { Writer fw = new OutputStreamWriter(new FileOutputStream(f), getDefaultEncoding()); WriterHelper cw = new WriterHelper(fw); Map m = new HashMap(); // oh the horror, a string comparison using !=... well, this // class is going to die soon so I won't touch it... if ((ft.getDataStoreId() != null) && (ft.getDataStoreId() != "")) { m.put("datastore", ft.getDataStoreId()); } cw.openTag("featureType", m); if ((ft.getName() != null) && (ft.getName() != "")) { cw.textTag("name", ft.getName()); } if ((ft.getAlias() != null) && !ft.getAlias().equals("")) { cw.textTag("alias", ft.getAlias()); } cw.comment("native wich EPGS code for the FeatureTypeInfoDTO"); cw.textTag("SRS", ft.getSRS() + ""); cw.textTag("SRSHandling", String.valueOf(ft.getSRSHandling())); if ((ft.getTitle() != null) && (ft.getTitle() != "")) { cw.textTag("title", ft.getTitle()); } if ((ft.getAbstract() != null) && (ft.getAbstract() != "")) { cw.textTag("abstract", ft.getAbstract()); } if ((ft.getWmsPath() != null) && (ft.getWmsPath() != "")) { cw.textTag("wmspath", ft.getWmsPath()); } cw.valueTag("numDecimals", ft.getNumDecimals() + ""); if ((ft.getKeywords() != null) && (ft.getKeywords().size() != 0)) { String s = ""; Iterator i = ft.getKeywords().iterator(); if (i.hasNext()) { s = i.next().toString(); while (i.hasNext()) { s = s + ", " + i.next().toString(); } } cw.textTag("keywords", s); } if ((ft.getMetadataLinks() != null) && (ft.getMetadataLinks().size() != 0)) { cw.openTag("metadataLinks"); for (Iterator it = ft.getMetadataLinks().iterator(); it.hasNext();) { MetaDataLink ml = (MetaDataLink) it.next(); Map mlAttr = new HashMap(); mlAttr.put("about", ml.getAbout()); mlAttr.put("type", ml.getType()); mlAttr.put("metadataType", ml.getMetadataType()); cw.textTag("metadataLink", mlAttr, ml.getContent()); } cw.closeTag("metadataLinks"); } if (ft.getLatLongBBox() != null) { m = new HashMap(); Envelope e = ft.getLatLongBBox(); // from creation, isn't stored otherwise if (!e.isNull()) { m.put("dynamic", "false"); m.put("minx", e.getMinX() + ""); m.put("miny", e.getMinY() + ""); m.put("maxx", e.getMaxX() + ""); m.put("maxy", e.getMaxY() + ""); } else { m.put("dynamic", "true"); } cw.attrTag("latLonBoundingBox", m); } if (ft.getNativeBBox() != null) { m = new HashMap(); Envelope e = ft.getNativeBBox(); // from creation, isn't stored otherwise if (!e.isNull()) { m.put("dynamic", "false"); m.put("minx", e.getMinX() + ""); m.put("miny", e.getMinY() + ""); m.put("maxx", e.getMaxX() + ""); m.put("maxy", e.getMaxY() + ""); } else { m.put("dynamic", "true"); } cw.attrTag("nativeBBox", m); } if ((ft.getDefaultStyle() != null) && (ft.getDefaultStyle() != "")) { cw.comment("the default style this FeatureTypeInfoDTO can be represented by.\n" + "at least must contain the \"default\" attribute "); m = new HashMap(); m.put("default", ft.getDefaultStyle()); final ArrayList styles = ft.getStyles(); if (styles.isEmpty()) { cw.attrTag("styles", m); } else { cw.openTag("styles", m); Iterator s_IT = styles.iterator(); while (s_IT.hasNext()) cw.textTag("style", (String) s_IT.next()); cw.closeTag("styles"); } } m = new HashMap(); if (ft.getCacheMaxAge() != null) { m.put("maxage", ft.getCacheMaxAge()); } if (ft.isCachingEnabled()) { m.put("enabled", "true"); } else { m.put("enabled", "false"); } cw.attrTag("cacheinfo", m); cw.attrTag("searchable", Collections.singletonMap("enabled", Boolean.toString(ft.isIndexingEnabled()))); if (ft.getRegionateAttribute()!= null) cw.attrTag( "regionateAttribute", Collections.singletonMap("value", ft.getRegionateAttribute()) ); if (ft.getRegionateStrategy()!= null && ft.getRegionateStrategy() != "best_guess") cw.attrTag( "regionateStrategy", Collections.singletonMap("value", ft.getRegionateStrategy()) ); cw.attrTag("regionateFeatureLimit", Collections.singletonMap("value", Integer.toString(ft.getRegionateFeatureLimit()))); if (ft.getDefinitionQuery() != null) { cw.openTag("definitionQuery"); /* * @REVISIT: strongly test this works. */ /* * StringWriter sw = new StringWriter(); * org.geotools.filter.XMLEncoder xe = new * org.geotools.filter.XMLEncoder(sw); * xe.encode(ft.getDefinitionQuery()); * cw.writeln(sw.toString()); cw.closeTag("definitionQuery"); */ FilterTransformer ftransformer = new FilterTransformer(); ftransformer.setOmitXMLDeclaration(true); ftransformer.setNamespaceDeclarationEnabled(false); String sfilter = ftransformer.transform(ft.getDefinitionQuery()); cw.writeln(sfilter); } cw.textTag("maxFeatures", String.valueOf(ft.getMaxFeatures())); cw.closeTag("featureType"); fw.close(); if (ft.getNameTemplate() != null) { PrintWriter ftl = new PrintWriter( new OutputStreamWriter( new FileOutputStream(new File(dir, "title.ftl")) ) ); ftl.println("${" + ft.getNameTemplate() + ".value}"); ftl.flush(); ftl.close(); } } catch (IOException e) { throw new ConfigurationException(e); } catch (TransformerException e) { throw new ConfigurationException(e); } } protected static void storeFeatureSchema(FeatureTypeInfoDTO fs, File dir) throws ConfigurationException { if ((fs.getSchemaBase() == null) || (fs.getSchemaBase() == "")) { // LOGGER.info( "No schema base" ); if (LOGGER.isLoggable(Level.FINER)) { LOGGER .finer(new StringBuffer(fs.getKey()).append(" has not schemaBase") .toString()); } return; } if ((fs.getSchemaName() == null) || (fs.getSchemaName() == "")) { // Should assume Null? // LOGGER.info( "No schema name" ); // Do we even have a field for // this? if (LOGGER.isLoggable(Level.FINER)) { LOGGER .finer(new StringBuffer(fs.getKey()).append(" has not schemaName") .toString()); } return; } File ftSchema = new File(dir, "schema.xml"); //backup file if it already exists if ( ftSchema.exists() ) { try { WriterUtils.backupFile( ftSchema, true ); } catch (IOException e) { LOGGER.severe( "Unable to backup: " + ftSchema.getAbsolutePath() ); } } File f = WriterUtils.initWriteFile(ftSchema, false); try { Writer fw = new OutputStreamWriter(new FileOutputStream(f), getDefaultEncoding()); storeFeatureSchema(fs, fw); fw.close(); } catch (IOException e) { throw new ConfigurationException(e); } } public static void storeFeatureSchema(FeatureTypeInfoDTO fs, Writer w) throws ConfigurationException { WriterHelper cw = new WriterHelper(w); HashMap m = new HashMap(); String t = fs.getSchemaName(); if (t != null) { if (!"_Type".equals(t.substring(t.length() - 5))) { t = t + "_Type"; } m.put("name", t); } cw.openTag("xs:complexType", m); cw.openTag("xs:complexContent"); m = new HashMap(); t = fs.getSchemaBase(); if (t != null) { m.put("base", t); } cw.openTag("xs:extension", m); cw.openTag("xs:sequence"); for (int i = 0; i < fs.getSchemaAttributes().size(); i++) { AttributeTypeInfoDTO ati = (AttributeTypeInfoDTO) fs.getSchemaAttributes().get(i); m = new HashMap(); m.put("nillable", "" + ati.isNillable()); m.put("minOccurs", "" + ati.getMinOccurs()); m.put("maxOccurs", "" + ati.getMaxOccurs()); NameSpaceTranslator nst_xs = NameSpaceTranslatorFactory.getInstance() .getNameSpaceTranslator("xs"); NameSpaceTranslator nst_gml = NameSpaceTranslatorFactory.getInstance() .getNameSpaceTranslator("gml"); if (!ati.isComplex()) { if (ati.getName() == ati.getType()) { String r = ""; NameSpaceElement nse = nst_xs.getElement(ati.getType()); if (nse == null) { nse = nst_gml.getElement(ati.getType()); } r = nse.getQualifiedTypeRefName(); m.put("ref", r); } else { m.put("name", ati.getName()); String r = ""; NameSpaceElement nse = nst_xs.getElement(ati.getType()); if (nse == null) { nse = nst_gml.getElement(ati.getType()); r = nse.getQualifiedTypeDefName(); // Def } else { r = nse.getQualifiedTypeRefName(); // Ref } m.put("type", r); } cw.attrTag("xs:element", m); } else { m.put("name", ati.getName()); cw.openTag("xs:element", m); cw.writeln(ati.getType()); cw.closeTag("xs:element"); } } cw.closeTag("xs:sequence"); cw.closeTag("xs:extension"); cw.closeTag("xs:complexContent"); cw.closeTag("xs:complexType"); } protected static void storeCoverages(File dir, DataDTO data) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("In method storeCoverages"); } // write them Iterator i = data.getCoverages().keySet().iterator(); while (i.hasNext()) { String s = (String) i.next(); CoverageInfoDTO cv = (CoverageInfoDTO) data.getCoverages().get(s); if (cv != null) { File dir2 = WriterUtils.initWriteFile(new File(dir, cv.getDirName()), true); storeCoverage(cv, dir2); } } File[] fa = dir.listFiles(); for (int j = 0; j < fa.length; j++) { if (fa[j].isDirectory()) { // find dir name i = data.getCoverages().values().iterator(); CoverageInfoDTO cvi = null; while ((cvi == null) && i.hasNext()) { CoverageInfoDTO cv = (CoverageInfoDTO) i.next(); if (cv.getDirName().equals(fa[j].getName())) { cvi = cv; } } if (cvi == null) { // delete it File[] t = fa[j].listFiles(); if (t != null) { for (int x = 0; x < t.length; x++) { // hold on to the data, but be sure to get rid of // the // geoserver config shit, as these were deleted. if (t[x].getName().equals("info.xml")) { // sorry for the hardcodes, I don't remember // if/where // we have these file names. t[x].delete(); } } } if (fa[j].listFiles().length == 0) { fa[j].delete(); } } } } } protected static void storeCoverage(CoverageInfoDTO cv, File dir) throws ConfigurationException { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("In method storeCoverage"); } File f = WriterUtils.initWriteFile(new File(dir, "info.xml"), false); try { Writer fw = new OutputStreamWriter(new FileOutputStream(f), getDefaultEncoding()); WriterHelper cw = new WriterHelper(fw); Map m = new HashMap(); if ((cv.getFormatId() != null) && (cv.getFormatId() != "")) { m.put("format", cv.getFormatId()); } cw.openTag("coverage", m); if ((cv.getName() != null) && (cv.getName() != "")) { cw.textTag("name", cv.getName()); } if ((cv.getLabel() != null) && (cv.getLabel() != "")) { cw.textTag("label", cv.getLabel()); } if ((cv.getDescription() != null) && (cv.getDescription() != "")) { cw.textTag("description", cv.getDescription()); } if ((cv.getWmsPath() != null) && (cv.getWmsPath() != "")) { cw.textTag("wmspath", cv.getWmsPath()); } m = new HashMap(); if ((cv.getMetadataLink() != null)) { m.put("about", cv.getMetadataLink().getAbout()); m.put("type", cv.getMetadataLink().getType()); m.put("metadataType", cv.getMetadataLink().getMetadataType()); cw.openTag("metadataLink", m); cw.writeln(cv.getMetadataLink().getContent()); cw.closeTag("metadataLink"); } if ((cv.getKeywords() != null) && (cv.getKeywords().size() != 0)) { String s = ""; Iterator i = cv.getKeywords().iterator(); if (i.hasNext()) { s = i.next().toString(); while (i.hasNext()) { s = s + "," + i.next().toString(); } } cw.textTag("keywords", s); } if ((cv.getDefaultStyle() != null) && (cv.getDefaultStyle() != "")) { cw.comment("the default style this CoverageInfoDTO can be represented by.\n" + "at least must contain the \"default\" attribute "); m = new HashMap(); m.put("default", cv.getDefaultStyle()); final ArrayList styles = cv.getStyles(); if (styles.isEmpty()) { cw.attrTag("styles", m); } else { cw.openTag("styles", m); Iterator s_IT = styles.iterator(); while (s_IT.hasNext()) cw.textTag("style", (String) s_IT.next()); cw.closeTag("styles"); } } // // // storing the envelope. // The native crs wkt is stored as the crs attribute. The user defined srs identifier as // the srsName atribute // // if (cv.getEnvelope() != null) { GeneralEnvelope e = cv.getEnvelope(); m = new HashMap(); String userDefinedCrsIdentifier = cv.getUserDefinedCrsIdentifier(); if ((userDefinedCrsIdentifier != null) && (userDefinedCrsIdentifier != "")) { m.put("srsName", userDefinedCrsIdentifier); } String nativeCrsWkt = cv.getNativeCrsWKT(); m.put("crs", nativeCrsWkt.replaceAll("\"", "'").replaceAll("\r\n", "\n")); if (!e.isNull()) { cw.comment("crs: native CRS definition, srsName: user defined CRS identifier"); cw.openTag("envelope", m); cw.textTag("pos", e.getLowerCorner().getOrdinate(0) + " " + e.getLowerCorner().getOrdinate(1)); cw.textTag("pos", e.getUpperCorner().getOrdinate(0) + " " + e.getUpperCorner().getOrdinate(1)); cw.closeTag("envelope"); } } // // // AlFa: storing the grid-geometry // // if (cv.getGrid() != null) { GridGeometry g = cv.getGrid(); MathTransform tx = g.getGridToCRS(); InternationalString[] dimNames = cv.getDimensionNames(); m = new HashMap(); m.put("dimension", new Integer(g.getGridRange().getDimension())); String lowers = ""; String upers = ""; for (int r = 0; r < g.getGridRange().getDimension(); r++) { lowers += (g.getGridRange().getLow(r) + " "); upers += (g.getGridRange().getHigh(r) + " "); } cw.openTag("grid", m); cw.textTag("low", lowers); cw.textTag("high", upers); if (dimNames != null) { for (int dn = 0; dn < dimNames.length; dn++) cw.textTag("axisName", dimNames[dn].toString()); } // // // AlFa: storing geo-transform // // if (tx instanceof AffineTransform) { AffineTransform aTX = (AffineTransform) tx; cw.openTag("geoTransform"); cw.textTag("scaleX", String.valueOf(aTX.getScaleX())); cw.textTag("scaleY", String.valueOf(aTX.getScaleY())); cw.textTag("shearX", String.valueOf(aTX.getShearX())); cw.textTag("shearY", String.valueOf(aTX.getShearY())); cw.textTag("translateX", String.valueOf(aTX.getTranslateX())); cw.textTag("translateY", String.valueOf(aTX.getTranslateY())); cw.closeTag("geoTransform"); } cw.closeTag("grid"); } if (cv.getDimensions() != null) { CoverageDimension[] dims = cv.getDimensions(); for (int d = 0; d < dims.length; d++) { Double[] nulls = dims[d].getNullValues(); cw.openTag("CoverageDimension"); cw.textTag("name", dims[d].getName()); cw.textTag("description", dims[d].getDescription()); if (dims[d].getRange() != null) { cw.openTag("interval"); cw.textTag("min", Double.toString(dims[d].getRange().getMinimum(true))); cw.textTag("max", Double.toString(dims[d].getRange().getMaximum(true))); cw.closeTag("interval"); } else { cw.openTag("interval"); cw.textTag("min", Double.toString(Double.NEGATIVE_INFINITY)); cw.textTag("max", Double.toString(Double.POSITIVE_INFINITY)); cw.closeTag("interval"); } if (nulls != null) { cw.openTag("nullValues"); for (int n = 0; n < nulls.length; n++) { cw.textTag("value", nulls[n].toString()); } cw.closeTag("nullValues"); } cw.closeTag("CoverageDimension"); } } cw.openTag("supportedCRSs"); if ((cv.getRequestCRSs() != null) && (cv.getRequestCRSs().size() != 0)) { String s = ""; Iterator i = cv.getRequestCRSs().iterator(); if (i.hasNext()) { s = i.next().toString(); while (i.hasNext()) { s = s + "," + i.next().toString(); } } cw.textTag("requestCRSs", s); } if ((cv.getResponseCRSs() != null) && (cv.getResponseCRSs().size() != 0)) { String s = ""; Iterator i = cv.getResponseCRSs().iterator(); if (i.hasNext()) { s = i.next().toString(); while (i.hasNext()) { s = s + "," + i.next().toString(); } } cw.textTag("responseCRSs", s); } cw.closeTag("supportedCRSs"); m = new HashMap(); if ((cv.getNativeFormat() != null) && (cv.getNativeFormat() != "")) { m.put("nativeFormat", cv.getNativeFormat()); } cw.openTag("supportedFormats", m); if ((cv.getSupportedFormats() != null) && (cv.getSupportedFormats().size() != 0)) { String s = ""; Iterator i = cv.getSupportedFormats().iterator(); if (i.hasNext()) { s = i.next().toString(); while (i.hasNext()) { s = s + "," + i.next().toString(); } } cw.textTag("formats", s); } cw.closeTag("supportedFormats"); m = new HashMap(); if ((cv.getDefaultInterpolationMethod() != null) && (cv.getDefaultInterpolationMethod() != "")) { m.put("default", cv.getDefaultInterpolationMethod()); } cw.openTag("supportedInterpolations", m); if ((cv.getInterpolationMethods() != null) && (cv.getInterpolationMethods().size() != 0)) { String s = ""; Iterator i = cv.getInterpolationMethods().iterator(); if (i.hasNext()) { s = i.next().toString(); while (i.hasNext()) { s = s + "," + i.next().toString(); } } cw.textTag("interpolationMethods", s); } cw.closeTag("supportedInterpolations"); // /////////////////////////////////////////////////////////////////////// // // STORING READ PARAMETERS // // /////////////////////////////////////////////////////////////////////// if ((cv.getParameters() != null) && (cv.getParameters().size() != 0)) { cw.openTag("parameters"); final Iterator i = cv.getParameters().keySet().iterator(); final HashMap temp = new HashMap(); while (i.hasNext()) { String key = (String) i.next(); if (cv.getParameters().get(key) != null) { temp.put("name", key); temp.put("value", cv.getParameters().get(key).toString().replaceAll( "\"", "'")); } cw.attrTag("parameter", temp); } cw.closeTag("parameters"); } cw.closeTag("coverage"); fw.close(); } catch (IOException e) { throw new ConfigurationException(e); } } /** * WriterUtils purpose. * * <p> * This is a static class which is used by XMLConfigWriter for File IO * validation tests. * </p> * * <p> * </p> * * @author dzwiers, Refractions Research, Inc. * @version $Id$ */ public static class WriterUtils { /** Used internally to create log information to detect errors. */ private static final Logger LOGGER = Logging.getLogger("org.vfny.geoserver.global"); /** * WriterUtils constructor. * * <p> * Static class, should never be used. * </p> */ private WriterUtils() { } /** * initFile purpose. * * <p> * Checks to ensure the handle exists. If the handle is a directory and * not created, it is created * </p> * * @param f * the File handle * @param isDir * true when the handle is intended to be a directory. * * @return The file passed in. * * @throws ConfigurationException * When an IO error occurs or the handle is invalid. */ public static File initFile(File f, boolean isDir) throws ConfigurationException { if (!f.exists()) { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer(new StringBuffer("Creating File: ").append(f.toString()) .toString()); } if (isDir) { if (!f.mkdir()) { throw new ConfigurationException( "Path specified does not have a valid file.\n" + f + "\n\n"); } } else { try { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.severe(new StringBuffer("Attempting to create file:").append( f.getAbsolutePath()).toString()); } if (!f.createNewFile()) { throw new ConfigurationException( "Path specified does not have a valid file.\n" + f + "\n\n"); } } catch (IOException e) { throw new ConfigurationException(e); } } } if (isDir && !f.isDirectory()) { throw new ConfigurationException("Path specified does not have a valid file.\n" + f + "\n\n"); } if (!isDir && !f.isFile()) { throw new ConfigurationException("Path specified does not have a valid file.\n" + f + "\n\n"); } if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer(new StringBuffer("File is valid: ").append(f).toString()); } return f; } /** * initFile purpose. * * <p> * Checks to ensure the handle exists and can be writen to. If the * handle is a directory and not created, it is created * </p> * * @param f * the File handle * @param isDir * true when the handle is intended to be a directory. * * @return The file passed in. * * @throws ConfigurationException * When an IO error occurs or the handle is invalid. */ public static File initWriteFile(File f, boolean isDir) throws ConfigurationException { initFile(f, isDir); if (!f.canWrite()) { throw new ConfigurationException("Cannot Write to file: " + f.toString()); } return f; } public static void backupFile( File f, boolean rename ) throws IOException { File b = new File( f.getAbsolutePath() + ".bak" ); //kill the pre-existing backup if it exists if ( b.exists() ) { WriterUtils.delete( b ); } if( rename ) { f.renameTo( b ); } else { FileUtils.copyFile( f, b ); } } /** * Backs up a directory by appending .bak to its name. */ public static void backupDirectory(File d) throws IOException { File b = new File( d.getAbsolutePath() + ".bak" ); if ( b.exists() ) { //kill the old backup //should be a directory, but check anyways if ( b.isDirectory() ) { deleteDirectory( b ); } else { b.delete(); } } //rename directory d.renameTo( b ); } /** * Deletes a file, handling the case in which it is a directory. */ public static void delete( File f ) throws IOException { if ( f.isDirectory() ) { WriterUtils.deleteDirectory( f ); } else { f.delete(); } } /** * Recursively deletes a directory. */ public static void deleteDirectory( File d ) throws IOException { File[] ls = d.listFiles(); for ( int i = 0; i < ls.length; i++ ) { if ( ls[i].isDirectory() ) { deleteDirectory(ls[i]); } else { ls[i].delete(); } } d.delete(); } } }