sascha@1015: package de.intevation.flys.artifacts.datacage; sascha@1015: sascha@1015: import java.util.Map; sascha@1015: import java.util.HashMap; sascha@1015: import java.util.List; sascha@1015: import java.util.ArrayList; sascha@1015: sascha@1015: import java.io.InputStream; sascha@1015: import java.io.IOException; sascha@1015: import java.io.File; sascha@1015: sascha@1015: import java.io.FileInputStream; sascha@1015: sascha@1015: import java.sql.Connection; sascha@1015: import java.sql.SQLException; sascha@1015: sascha@1015: import org.apache.log4j.Logger; sascha@1015: sascha@1015: import org.w3c.dom.Document; sascha@1015: import org.w3c.dom.Node; sascha@1015: sascha@1015: import org.hibernate.Session; sascha@1015: sascha@1015: import org.hibernate.jdbc.Work; sascha@1015: sascha@1015: import de.intevation.artifacts.common.utils.Config; sascha@1015: import de.intevation.artifacts.common.utils.XMLUtils; sascha@1716: import de.intevation.artifacts.common.utils.StringUtils; sascha@1015: sascha@1015: import de.intevation.flys.artifacts.FLYSArtifact; sascha@1015: sascha@1015: import de.intevation.flys.backend.SessionHolder; sascha@1015: sascha@1015: import de.intevation.artifactdatabase.data.StateData; sascha@1015: sascha@1015: import de.intevation.flys.artifacts.datacage.templating.Builder; sascha@1015: sascha@1015: public class Recommendations sascha@1015: { sascha@1015: private static Logger log = Logger.getLogger(Recommendations.class); sascha@1015: sascha@1030: private static final boolean DEVELOPMENT_MODE = sascha@1030: Boolean.getBoolean("flys.datacage.recommendations.development"); sascha@1030: sascha@1046: public static final String XPATH_TEMPLATE = sascha@1046: "/artifact-database/metadata/template/text()"; sascha@1015: sascha@1046: public static final String DEFAULT_TEMPLATE_PATH = sascha@1046: "${artifacts.config.dir}/meta-data.xml"; sascha@1015: sascha@1015: private static Recommendations INSTANCE; sascha@1015: sascha@1030: public static class BuilderProvider sascha@1030: { sascha@1030: protected Builder builder; sascha@1030: sascha@1030: public BuilderProvider() { sascha@1030: } sascha@1030: sascha@1030: public BuilderProvider(Builder builder) { sascha@1030: this.builder = builder; sascha@1030: } sascha@1030: sascha@1030: public Builder getBuilder() { sascha@1030: return builder; sascha@1030: } sascha@1030: } // class BuilderProvider sascha@1030: sascha@1030: public static class FileBuilderProvider sascha@1030: extends BuilderProvider sascha@1030: { sascha@1030: protected File file; sascha@1030: protected long lastModified; sascha@1030: sascha@1030: public FileBuilderProvider() { sascha@1030: } sascha@1030: sascha@1030: public FileBuilderProvider(File file) { sascha@1030: this.file = file; sascha@1030: lastModified = Long.MIN_VALUE; sascha@1030: } sascha@1030: sascha@1030: @Override sascha@1030: public synchronized Builder getBuilder() { sascha@1030: long modified = file.lastModified(); sascha@1030: if (modified > lastModified) { sascha@1030: lastModified = modified; sascha@1030: try { sascha@1030: Document template = loadTemplate(file); sascha@1030: builder = new Builder(template); sascha@1030: } sascha@1030: catch (IOException ioe) { sascha@1030: log.error(ioe); sascha@1030: } sascha@1030: } sascha@1030: return builder; sascha@1030: } sascha@1030: sascha@1030: public BuilderProvider toStaticProvider() { sascha@1030: return new BuilderProvider(builder); sascha@1030: } sascha@1030: } // class BuilderProvider sascha@1030: sascha@1046: protected BuilderProvider builderProvider; sascha@1015: sascha@1015: public Recommendations() { sascha@1015: } sascha@1015: sascha@1046: public Recommendations(BuilderProvider builderProvider) { sascha@1046: this.builderProvider = builderProvider; sascha@1015: } sascha@1015: sascha@1046: public Builder getBuilder() { sascha@1046: return builderProvider.getBuilder(); sascha@1015: } sascha@1015: sascha@1015: protected static void artifactToParameters( sascha@3076: FLYSArtifact artifact, sascha@1015: Map parameters sascha@1015: ) { sascha@1716: parameters.put("CURRENT-STATE-ID", artifact.getCurrentStateId()); sascha@1716: parameters.put("ARTIFACT-ID", artifact.identifier()); sascha@1015: sascha@1015: for (StateData sd: artifact.getAllData()) { sascha@1015: Object value = sd.getValue(); sascha@1015: if (value == null) { sascha@1015: continue; sascha@1015: } sascha@1716: String key = sd.getName().replace('.', '-').toUpperCase(); sascha@1015: parameters.put(key, value); sascha@1015: } sascha@1015: } sascha@1015: sascha@1716: public static void convertKeysToUpperCase( sascha@1716: Map src, sascha@1716: Map dst sascha@1716: ) { sascha@1716: for (Map.Entry entry: src.entrySet()) { sascha@1716: dst.put(entry.getKey().toUpperCase(), entry.getValue()); sascha@1716: } sascha@1716: } sascha@1716: sascha@1015: public void recommend( sascha@1015: FLYSArtifact artifact, sascha@1015: String userId, sascha@1015: String [] outs, sascha@1015: Map extraParameters, sascha@1015: Node result sascha@1015: ) { sascha@1015: Map parameters = new HashMap(); sascha@1015: sascha@1015: if (extraParameters != null) { sascha@1716: convertKeysToUpperCase(extraParameters, parameters); sascha@1015: } sascha@1015: sascha@1015: if (userId != null) { sascha@1716: parameters.put("USER-ID", userId); sascha@1015: } sascha@1015: sascha@1015: if (artifact != null) { sascha@1015: artifactToParameters(artifact, parameters); sascha@1015: } sascha@1015: sascha@1716: parameters.put("ARTIFACT-OUTS", StringUtils.toUpperCase(outs)); sascha@1015: sascha@1716: parameters.put("PARAMETERS", parameters); sascha@1015: sascha@1015: recommend(parameters, userId, result); sascha@1015: } sascha@1015: sascha@1015: public void recommend( sascha@1015: Map parameters, sascha@1015: String userId, sascha@1015: Node result sascha@1015: ) { sascha@1015: recommend(parameters, userId, result, SessionHolder.HOLDER.get()); sascha@1015: } sascha@1015: sascha@1015: public void recommend( sascha@1015: final Map parameters, sascha@1015: final String userId, sascha@1015: final Node result, sascha@1015: Session session sascha@1015: ) { sascha@1015: session.doWork(new Work() { sascha@1015: @Override sascha@1015: public void execute(Connection systemConnection) sascha@1015: throws SQLException sascha@1015: { sascha@1015: List connections = sascha@1015: new ArrayList(2); sascha@1015: sascha@1046: Connection userConnection = userId != null sascha@1046: ? DBConfig sascha@1015: .getInstance() sascha@1015: .getDBConnection() sascha@1046: .getDataSource() sascha@1046: .getConnection() sascha@1046: : null; sascha@1015: sascha@1046: try { sascha@1046: if (userConnection != null) { sascha@1015: connections.add(new Builder.NamedConnection( sascha@1022: Builder.CONNECTION_USER, userConnection, false)); sascha@1046: } sascha@1015: sascha@1015: connections.add(new Builder.NamedConnection( sascha@1022: Builder.CONNECTION_SYSTEM, systemConnection, true)); sascha@1015: sascha@1046: getBuilder().build(connections, result, parameters); sascha@1046: } sascha@1046: finally { sascha@1046: if (userConnection != null) { sascha@1046: userConnection.close(); sascha@1046: } sascha@1015: } sascha@1015: } sascha@1015: }); sascha@1015: } sascha@1015: sascha@1015: public static synchronized Recommendations getInstance() { sascha@1015: if (INSTANCE == null) { sascha@1015: INSTANCE = createRecommendations(); sascha@1015: } sascha@1015: return INSTANCE; sascha@1015: } sascha@1015: sascha@1015: protected static Document loadTemplate(File file) throws IOException { sascha@1015: InputStream in = null; sascha@1015: sascha@1015: try { sascha@1015: in = new FileInputStream(file); sascha@1015: sascha@1015: Document template = XMLUtils.parseDocument(in); sascha@1015: sascha@1015: if (template == null) { sascha@1015: throw new IOException("cannot load template"); sascha@1015: } sascha@1015: return template; sascha@1015: } sascha@1015: finally { sascha@1015: if (in != null) { sascha@1015: try { sascha@1015: in.close(); sascha@1015: } sascha@1015: catch (IOException ioe) { sascha@1015: log.error(ioe); sascha@1015: } sascha@1015: } sascha@1015: } sascha@1015: } sascha@1015: sascha@1046: public static Recommendations createRecommendations(File file) { sascha@1015: log.debug("Recommendations.createBuilder"); sascha@1015: sascha@1046: if (!file.isFile() || !file.canRead()) { sascha@1046: log.error("Cannot open template file '" + file + "'"); sascha@1015: return null; sascha@1015: } sascha@1015: sascha@1046: FileBuilderProvider fbp = new FileBuilderProvider(file); sascha@1015: sascha@1046: if (fbp.getBuilder() == null) { sascha@1030: log.error("failed loading builder"); sascha@1015: return null; sascha@1015: } sascha@1030: sascha@1046: BuilderProvider bp = DEVELOPMENT_MODE sascha@1046: ? fbp sascha@1046: : fbp.toStaticProvider(); sascha@1030: sascha@1046: return new Recommendations(bp); sascha@1015: } sascha@1015: sascha@1015: protected static Recommendations createRecommendations() { sascha@1015: log.debug("Recommendations.createRecommendations"); sascha@1015: sascha@1046: String path = Config.getStringXPath(XPATH_TEMPLATE); sascha@1015: sascha@1046: if (path == null) { sascha@1046: path = DEFAULT_TEMPLATE_PATH; sascha@1015: } sascha@1015: sascha@1046: path = Config.replaceConfigDir(path); sascha@1015: sascha@1046: log.info("Meta data template: " + path); sascha@1046: sascha@1046: return createRecommendations(new File(path)); sascha@1015: } sascha@1015: } sascha@1015: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :