ingo@1095: package de.intevation.flys.utils; ingo@1095: felix@1150: import org.apache.log4j.Logger; ingo@1740: ingo@1740: import java.text.NumberFormat; ingo@1105: import java.util.HashMap; ingo@1740: import java.util.List; ingo@1105: import java.util.Map; ingo@1105: ingo@1105: import javax.xml.xpath.XPathConstants; ingo@1105: ingo@1105: import org.w3c.dom.Document; ingo@1105: ingo@1845: import org.hibernate.SessionFactory; ingo@1845: import org.hibernate.impl.SessionFactoryImpl; ingo@1845: ingo@1095: import gnu.trove.TDoubleArrayList; ingo@1095: ingo@1174: import de.intevation.artifacts.Artifact; ingo@1118: import de.intevation.artifacts.CallContext; ingo@1118: ingo@1105: import de.intevation.artifacts.common.utils.Config; ingo@1105: import de.intevation.artifacts.common.utils.XMLUtils; ingo@1105: ingo@1845: import de.intevation.flys.backend.SessionFactoryProvider; ingo@1845: felix@1777: import de.intevation.flys.artifacts.context.FLYSContext; ingo@1095: import de.intevation.flys.artifacts.FLYSArtifact; ingo@1740: import de.intevation.flys.artifacts.WINFOArtifact; felix@1099: import de.intevation.flys.artifacts.model.RiverFactory; ingo@1740: import de.intevation.flys.model.Gauge; ingo@1740: import de.intevation.flys.model.MainValue; felix@1099: import de.intevation.flys.model.River; ingo@1095: ingo@1095: public class FLYSUtils { ingo@1095: felix@1150: /** The logger that is used in this utility. */ felix@1150: private static Logger logger = Logger.getLogger(FLYSUtils.class); felix@1150: ingo@1095: public static enum KM_MODE { RANGE, LOCATIONS, NONE }; ingo@1095: ingo@1105: public static final String XPATH_RIVER_PROJECTION = ingo@1105: "/artifact-database/floodmap/river[@name=$name]/srid/@value"; ingo@1105: ingo@1129: public static final String XPATH_SHAPEFILE_DIR = ingo@1129: "/artifact-database/floodmap/shapefile-path/@value"; ingo@1129: ingo@1129: public static final String XPATH_VELOCITY_LOGFILE = ingo@1129: "/artifact-database/floodmap/velocity/logfile/@path"; ingo@1129: ingo@1129: public static final String XPATH_MAPSERVER_URL = ingo@1129: "/artifact-database/floodmap/mapserver/server/@path"; ingo@1129: ingo@1129: public static final String XPATH_MAPFILE_PATH = ingo@1129: "/artifact-database/floodmap/mapserver/mapfile/@path"; ingo@1129: ingo@1129: public static final String XPATH_MAPFILE_TEMPLATE = ingo@1129: "/artifact-database/floodmap/mapserver/map-template/@path"; ingo@1129: ingo@1129: public static final String XPATH_MAPSERVER_TEMPLATE_PATH = ingo@1129: "/artifact-database/floodmap/mapserver/templates/@path"; ingo@1129: ingo@1095: ingo@1095: private FLYSUtils() { ingo@1095: } ingo@1095: ingo@1095: ingo@1118: public static FLYSArtifact getArtifact(String uuid, CallContext context) { felix@1150: try { ingo@1174: Artifact artifact = context.getDatabase().getRawArtifact(uuid); ingo@1174: ingo@1174: if (artifact == null) { ingo@1174: logger.error("Artifact '" + uuid + "' does not exist."); ingo@1174: return null; ingo@1174: } ingo@1174: ingo@1174: if (!(artifact instanceof FLYSArtifact)) { ingo@1174: logger.error("Artifact '" +uuid+ "' is no valid FLYSArtifact."); ingo@1174: return null; ingo@1174: } ingo@1174: ingo@1174: return (FLYSArtifact) artifact; felix@1150: } felix@1150: // TODO: catch more selective felix@1150: catch (Exception e) { felix@1150: logger.error("Cannot get FLYSArtifact " + uuid + " from database (" + e.getMessage() + ")."); felix@1150: return null; felix@1150: } ingo@1118: } ingo@1118: ingo@1118: ingo@1129: /** felix@1777: * Returns the FLYSContext from context object. felix@1777: * felix@1777: * @param context The CallContext or the FLYSContext. felix@1777: * felix@1777: * @return the FLYSContext. felix@1777: */ felix@1777: public static FLYSContext getFlysContext(Object context) { felix@1777: return context instanceof FLYSContext felix@1777: ? (FLYSContext) context felix@1777: : (FLYSContext) ((CallContext) context).globalContext(); felix@1777: } felix@1777: felix@1777: felix@1777: /** ingo@1129: * Convinience function to retrieve an XPath as string with replaced config ingo@1129: * directory. ingo@1129: * ingo@1129: * @param xpath The XPath expression. ingo@1129: * ingo@1129: * @return a string with replaced config directory. ingo@1129: */ ingo@1129: public static String getXPathString(String xpath) { ingo@1129: String tmp = Config.getStringXPath(xpath); ingo@1129: tmp = Config.replaceConfigDir(tmp); ingo@1129: ingo@1129: return tmp; ingo@1129: } ingo@1129: ingo@1129: ingo@1845: public static boolean isUsingOracle() { ingo@1845: SessionFactory sf = SessionFactoryProvider.getSessionFactory(); ingo@1845: ingo@1845: String d = SessionFactoryProvider.getDriver((SessionFactoryImpl) sf); ingo@1845: ingo@1845: return d != null ? d.indexOf("Oracle") >= 0 : false; ingo@1845: } ingo@1845: ingo@1845: ingo@1095: public static KM_MODE getKmRangeMode(FLYSArtifact flys) { felix@1099: String mode = flys.getDataAsString("ld_mode"); ingo@1095: ingo@1095: if (mode == null || mode.length() == 0) { ingo@1095: return KM_MODE.NONE; ingo@1095: } ingo@1095: else if (mode.equals("distance")) { ingo@1095: return KM_MODE.RANGE; ingo@1095: } ingo@1095: else if (mode.equals("locations")) { ingo@1095: return KM_MODE.LOCATIONS; ingo@1095: } ingo@1095: else { ingo@1095: return KM_MODE.NONE; ingo@1095: } ingo@1095: } ingo@1095: ingo@1095: ingo@1095: public static double[] getKmRange(FLYSArtifact flys) { ingo@1095: switch (getKmRangeMode(flys)) { ingo@1095: case RANGE: { ingo@1095: return getKmFromTo(flys); ingo@1095: } ingo@1095: ingo@1095: case LOCATIONS: { ingo@1095: double[] locs = getLocations(flys); ingo@1095: return new double[] { locs[0], locs[locs.length-1] }; ingo@1095: } ingo@1095: ingo@1095: case NONE: { ingo@1095: double[] locs = getLocations(flys); ingo@1095: if (locs != null) { ingo@1095: return new double[] { locs[0], locs[locs.length-1] }; ingo@1095: } ingo@1095: else { ingo@1095: return getKmFromTo(flys); ingo@1095: } ingo@1095: } ingo@1095: } ingo@1095: ingo@1095: return new double[] { Double.NaN, Double.NaN }; ingo@1095: } ingo@1095: ingo@1095: ingo@1095: public static double[] getKmFromTo(FLYSArtifact flys) { ingo@1095: String strFrom = flys.getDataAsString("ld_from"); ingo@1095: String strTo = flys.getDataAsString("ld_to"); ingo@1095: ingo@1095: if (strFrom == null || strTo == null) { ingo@1095: return null; ingo@1095: } ingo@1095: ingo@1095: try { ingo@1095: return new double[] { ingo@1095: Double.parseDouble(strFrom), ingo@1095: Double.parseDouble(strTo) }; ingo@1095: } ingo@1095: catch (NumberFormatException nfe) { ingo@1095: return null; ingo@1095: } ingo@1095: } ingo@1095: ingo@1095: ingo@1095: public static double[] getLocations(FLYSArtifact flys) { ingo@1095: String locationStr = flys.getDataAsString("ld_locations"); ingo@1095: ingo@1095: if (locationStr == null || locationStr.length() == 0) { ingo@1095: return null; ingo@1095: } ingo@1095: ingo@1095: String[] tmp = locationStr.split(" "); ingo@1095: TDoubleArrayList locations = new TDoubleArrayList(); ingo@1095: ingo@1095: for (String l: tmp) { ingo@1095: try { ingo@1095: locations.add(Double.parseDouble(l)); ingo@1095: } ingo@1095: catch (NumberFormatException nfe) { ingo@1095: } ingo@1095: } ingo@1095: ingo@1095: locations.sort(); ingo@1095: ingo@1095: return locations.toNativeArray(); ingo@1095: } felix@1099: felix@1099: felix@1099: /** felix@1099: * Returns the selected River object based on the 'river' data that might felix@1099: * have been inserted by the user. felix@1099: * felix@1099: * @return the selected River or null if no river has been chosen yet. felix@1099: */ felix@1099: public static River getRiver(FLYSArtifact flys) { felix@1099: String sRiver = flys.getDataAsString("river"); felix@1099: felix@1099: return (sRiver != null) felix@1099: ? RiverFactory.getRiver(sRiver) felix@1099: : null; felix@1099: } ingo@1105: ingo@1105: ingo@1105: /** ingo@1105: * Extracts the SRID defined in the global configuration for the river ingo@1105: * specified in artifact. ingo@1105: * ingo@1105: * @param artifact The FLYSArtifact that stores the name of the river. ingo@1105: * ingo@1105: * @return the SRID as string (e.g. "31466"). ingo@1105: */ ingo@1105: public static String getRiverSrid(FLYSArtifact artifact) { ingo@1105: String river = artifact.getDataAsString("river"); ingo@1105: ingo@1105: if (river == null || river.length() == 0) { ingo@1105: return null; ingo@1105: } ingo@1105: ingo@1805: return getRiverSrid(river); ingo@1805: } ingo@1805: ingo@1805: ingo@1805: public static String getRiverSrid(String rivername) { ingo@1105: Map variables = new HashMap(1); ingo@1805: variables.put("name", rivername); ingo@1105: ingo@1105: Document cfg = Config.getConfig(); ingo@1105: ingo@1105: return (String) XMLUtils.xpath( ingo@1105: cfg, ingo@1105: XPATH_RIVER_PROJECTION, ingo@1105: XPathConstants.STRING, ingo@1105: null, ingo@1105: variables); ingo@1105: } ingo@1740: ingo@1740: ingo@1740: public static String createWspWTitle( ingo@1740: WINFOArtifact winfo, ingo@1740: CallContext cc, ingo@1740: String name ingo@1740: ) { ingo@1740: String[] parts = name.split("="); ingo@1740: ingo@1740: NumberFormat nf = Formatter.getWaterlevelW(cc); ingo@1740: ingo@1740: String namedMainValue = null; ingo@1740: ingo@1740: boolean isQ = winfo.isQ(); ingo@1740: boolean isFree = winfo.isFreeQ(); ingo@1740: ingo@1740: double v; ingo@1740: ingo@1740: try { ingo@1740: v = Double.valueOf(parts[1]); ingo@1740: ingo@1740: namedMainValue = getNamedMainValue(winfo.getGauge(), v); ingo@1740: } ingo@1740: catch (NumberFormatException nfe) { ingo@1740: logger.warn("Cannot parse Double of: '" + parts[1] + "'"); ingo@1740: return name; ingo@1740: } ingo@1740: ingo@1740: String prefix = null; ingo@1740: ingo@1740: if (isQ && !isFree && namedMainValue != null) { ingo@1740: return "W (" + namedMainValue + ")"; ingo@1740: } ingo@1740: ingo@1740: if (isQ) { ingo@1740: prefix = "Q="; ingo@1740: } ingo@1740: ingo@1740: return prefix == null ingo@1740: ? "W(" + nf.format(v) + ")" ingo@1740: : "W(" + prefix + nf.format(v) + ")"; ingo@1740: } ingo@1740: ingo@1740: ingo@1740: public static String createWspQTitle( ingo@1740: WINFOArtifact winfo, ingo@1740: CallContext cc, ingo@1740: String name ingo@1740: ) { ingo@1740: String[] parts = name.split("="); ingo@1740: ingo@1740: NumberFormat nf = Formatter.getWaterlevelQ(cc); ingo@1740: ingo@1740: String namedMainValue = null; ingo@1740: ingo@1740: boolean isQ = winfo.isQ(); ingo@1740: boolean isFree = winfo.isFreeQ(); ingo@1740: ingo@1740: double v; ingo@1740: ingo@1740: try { ingo@1740: v = Double.valueOf(parts[1]); ingo@1740: ingo@1740: namedMainValue = getNamedMainValue(winfo.getGauge(), v); ingo@1740: } ingo@1740: catch (NumberFormatException nfe) { ingo@1740: logger.warn("Cannot parse Double of: '" + parts[1] + "'"); ingo@1740: return name; ingo@1740: } ingo@1740: ingo@1740: String prefix = null; ingo@1740: ingo@1740: if (isQ && !isFree && namedMainValue != null) { ingo@1740: return namedMainValue; ingo@1740: } ingo@1740: ingo@1740: if (!isQ) { ingo@1740: prefix = "W="; ingo@1740: } ingo@1740: ingo@1740: return prefix == null ingo@1740: ? "Q(" + nf.format(v) + ")" ingo@1740: : "Q(" + prefix + nf.format(v) + ")"; ingo@1740: } ingo@1740: ingo@1740: ingo@1740: public static String getNamedMainValue(Gauge gauge, double value) { ingo@1740: List mainValues = gauge.getMainValues(); ingo@1740: logger.debug("Search named main value for: " + value); ingo@1740: ingo@1740: for (MainValue mv: mainValues) { ingo@1740: if (mv.getValue().doubleValue() == value) { ingo@1740: logger.debug("Found named main value: " + mv.getMainValue().getName()); ingo@1740: return mv.getMainValue().getName(); ingo@1740: } ingo@1740: } ingo@1740: ingo@1740: logger.debug("Did not find a named main value for: " + value); ingo@1740: return null; ingo@1740: } ingo@1792: ingo@1792: ingo@1792: /** ingo@1792: * Returns the URL of user mapfile for the owner of Artifact ingo@1792: * artifactId. ingo@1792: * ingo@1792: * @param artifactId The UUID of an artifact. ingo@1792: * ingo@1792: * @return the URL of the user wms. ingo@1792: */ ingo@1792: public static String getUserWMSUrl(String artifactId) { ingo@1792: String url = getXPathString(XPATH_MAPSERVER_URL); ingo@1792: url = url + "user-wms"; ingo@1792: ingo@1792: return url; ingo@1792: } ingo@1095: } ingo@1105: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :