Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/WMSDBArtifact.java @ 4150:0f60efc39953
Workaround for #961
author | Christian Lins <christian.lins@intevation.de> |
---|---|
date | Tue, 16 Oct 2012 12:17:53 +0200 |
parents | 9fac337192c9 |
children | a2735a4bf75e |
line wrap: on
line source
package de.intevation.flys.artifacts; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import java.util.regex.Matcher; import org.w3c.dom.Document; import org.apache.log4j.Logger; import org.hibernate.impl.SessionFactoryImpl; import com.vividsolutions.jts.geom.Envelope; import de.intevation.artifacts.Artifact; import de.intevation.artifacts.ArtifactFactory; import de.intevation.artifacts.CallMeta; import de.intevation.artifacts.common.utils.FileTools; import de.intevation.artifactdatabase.data.DefaultStateData; import de.intevation.artifactdatabase.state.Facet; import de.intevation.artifactdatabase.state.State; import de.intevation.flys.backend.SessionFactoryProvider; import de.intevation.flys.artifacts.resources.Resources; import de.intevation.flys.artifacts.states.DefaultState; import de.intevation.flys.artifacts.model.map.WMSDBLayerFacet; import de.intevation.flys.utils.FLYSUtils; import de.intevation.flys.utils.MapfileGenerator; public abstract class WMSDBArtifact extends StaticFLYSArtifact { private static final Logger logger = Logger.getLogger(WMSDBArtifact.class); public static final Pattern DB_URL_PATTERN = Pattern.compile("(.*)\\/\\/(.*):([0-9]+)\\/([a-zA-Z]+)"); public static final Pattern DB_PSQL_URL_PATTERN = Pattern.compile("(.*)\\/\\/(.*):([0-9]+)\\/([a-zA-Z0-9]+)"); @Override public void setup( String identifier, ArtifactFactory factory, Object context, CallMeta callMeta, Document data) { logger.debug("WMSDBArtifact.setup"); super.setup(identifier, factory, context, callMeta, data); String ids = getDatacageIDValue(data); if (ids != null && ids.length() > 0) { addData("ids", new DefaultStateData("ids", null, null, ids)); } else { throw new IllegalArgumentException("No attribute 'ids' found!"); } List<Facet> fs = new ArrayList<Facet>(); WMSDBState state = (WMSDBState) getCurrentState(context); state.computeInit(this, hash(), context, callMeta, fs); if (!fs.isEmpty()) { facets.put(getCurrentStateId(), fs); } } @Override protected void initialize( Artifact artifact, Object context, CallMeta callMeta) { // do nothing } @Override protected State getState(Object context, String stateID) { return getCurrentState(context); } /** * Get a list containing the one and only State. * @param context ignored. * @return list with one and only state. */ @Override protected List<State> getStates(Object context) { ArrayList<State> states = new ArrayList<State>(); states.add(getCurrentState(context)); return states; } public static abstract class WMSDBState extends DefaultState { private static final Logger logger = Logger.getLogger(WMSDBState.class); protected FLYSArtifact artifact; protected String name; protected int riverId; public WMSDBState() {} public WMSDBState(FLYSArtifact artifact) { this.artifact = artifact; this.name = null; this.riverId = 0; } @Override public Object computeInit( FLYSArtifact artifact, String hash, Object context, CallMeta meta, List<Facet> facets ) { logger.debug("WMSDBState.computeInit"); String type = getFacetType(); WMSDBLayerFacet facet = new WMSDBLayerFacet( 0, type, getTitle(meta), ComputeType.INIT, getID(), hash, getUrl()); String name = type + "-" + artifact.identifier(); facet.addLayer(name); facet.setExtent(getExtent()); facet.setOriginalExtent(getExtent(true)); facet.setSrid(getSrid()); facet.setData(getDataString()); facet.setFilter(getFilter()); facet.setGeometryType(getGeometryType()); facet.setConnection(getConnection()); facet.setConnectionType(getConnectionType()); facet.setLabelItem(getLabelItem()); facets.add(facet); return null; } /** * This method returns a connection string for databases used by * Mapserver's Mapfile. * * @return A connection string for Mapserver. */ protected String getConnection() { SessionFactoryImpl sf = (SessionFactoryImpl) SessionFactoryProvider.getSessionFactory(); String user = SessionFactoryProvider.getUser(sf); String pass = SessionFactoryProvider.getPass(sf); String url = SessionFactoryProvider.getURL(sf); logger.debug("Parse connection url: " + url); Matcher m = DB_URL_PATTERN.matcher(url); if (!m.matches()) { logger.warn("Could not parse Connection string." + "Try to parse PostgreSQL string."); // maybe this is a PostgreSQL connection... return getPostgreSQLConnection(); } logger.debug("Groups for connection string: " + m.groupCount()); int groups = m.groupCount(); for (int i = 0; i <= groups; i++) { logger.debug("Group " + i + ": " + m.group(i)); } String connection = null; if (FLYSUtils.isUsingOracle()) { if (groups < 3) { logger.warn("Could only partially parse connection string."); return null; } String host = m.group(2); String port = m.group(3); connection = user + "/" + pass + "@" + host; } else { if (groups < 4) { logger.warn("Could only partially parse connection string."); return null; } String host = m.group(2); String port = m.group(3); String db = m.group(4); StringBuilder sb = new StringBuilder(); sb.append("dbname=" + db); sb.append("host='" + host + "'"); sb.append("port=" + port); sb.append("password='" + pass + "'"); sb.append("sslmode=disable"); connection = sb.toString(); } logger.debug("Created connection: '" + connection + "'"); return connection; } protected String getPostgreSQLConnection() { SessionFactoryImpl sf = (SessionFactoryImpl) SessionFactoryProvider.getSessionFactory(); String user = SessionFactoryProvider.getUser(sf); String pass = SessionFactoryProvider.getPass(sf); String url = SessionFactoryProvider.getURL(sf); Matcher m = DB_PSQL_URL_PATTERN.matcher(url); if (!m.matches()) { logger.warn("Could not parse PostgreSQL Connection string."); return null; } int groups = m.groupCount(); logger.debug("Groups for PostgreSQL connection string: " + groups); if (logger.isDebugEnabled()) { for (int i = 0; i <= groups; i++) { logger.debug("Group " + i + ": " + m.group(i)); } } String connection = null; if (groups < 4) { logger.warn("Could only partially parse connection string."); return null; } String host = m.group(2); String port = m.group(3); String db = m.group(4); StringBuilder sb = new StringBuilder(); sb.append("dbname=" + db); sb.append(" host='" + host + "'"); sb.append(" port=" + port); sb.append(" user=" + user); sb.append(" password='" + pass + "'"); sb.append(" sslmode=disable"); connection = sb.toString(); logger.debug("Created connection: '" + connection + "'"); return connection; } protected String getConnectionType() { return FLYSUtils.isUsingOracle() ? "oraclespatial" : "postgis"; } protected String getLabelItem() { return null; } public int getRiverId() { if (riverId == 0) { String ids = artifact.getDataAsString("ids"); String[] parts = ids.split(";"); try { riverId = Integer.parseInt(parts[0]); } catch (NumberFormatException nfe) { logger.error("Cannot parse river id from '" + parts[0] + "'"); } } return riverId; } /** * Returns the name of the WMS layer. This method extracts the name * from 'ids' data string. It is expected, that the 'ids' string is * seperated by ';' and that the name is placed at index 1. * * @return the name of the WMS layer. */ public String getName() { if (name == null) { String ids = artifact.getDataAsString("ids"); String parts[] = ids != null ? ids.split(";") : null; if (parts != null && parts.length >= 2) { name = parts[1]; } } return name; } /** * Returns the name of the layer (returned by getName()) or the layer * type if the name is empty. The layer type is created by an i18n * string of getFacetType(). * * @param meta A CallMeta used for i18n. * * @return the name of the layer or its type if name is empty. */ protected String getTitle(CallMeta meta) { String name = getName(); return name != null && name.length() > 0 ? name : Resources.getMsg( meta, getFacetType(), getFacetType()); } @Override public void endOfLife(Artifact owner, Object context) { logger.info("Destroy WMSDBState: " + getID()); String p = FLYSUtils.getXPathString(FLYSUtils.XPATH_SHAPEFILE_DIR); File dir = new File(p, owner.identifier()); if (dir != null && dir.exists()) { logger.debug("Try to delete directory '" + dir + "'"); FileTools.deleteRecursive(dir); MapfileGenerator.getInstance().update(); } } /** * This method returns the extent of a DB layer in the projection of the * database. * * @return the extent of the DB layer in the projection of the database. */ protected Envelope getExtent() { return getExtent(false); } protected abstract String getFacetType(); protected abstract String getUrl(); protected abstract String getSrid(); /** * This method returns the extent of the DB layer. The projection of the * extent depends on the <i>reproject</i> parameter. If reproject is set, * the extent is reprojected into the original projection which is * specified in the configuration. Otherwise, the projection of the * database is used. * * @param reproject True, to reproject the extent into the projection * specified in the configuration. * * @return the extent of the database layer. */ protected abstract Envelope getExtent(boolean reproject); protected abstract String getFilter(); protected abstract String getDataString(); protected abstract String getGeometryType(); } // end of WMSDBState } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :