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 javax.sql.DataSource; 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@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@1015: public static final String XPATH_SYSTEM_TEMPLATE = sascha@1015: "/artifact-database/metadata/system/@template"; sascha@1015: sascha@1015: public static final String XPATH_USER_TEMPLATE = sascha@1015: "/artifact-database/metadata/user/@template"; 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@1030: protected BuilderProvider systemBuilderProvider; sascha@1030: protected BuilderProvider userBuilderProvider; sascha@1015: sascha@1015: public Recommendations() { sascha@1015: } sascha@1015: sascha@1030: public Recommendations( sascha@1030: BuilderProvider systemBuilderProvider, sascha@1030: BuilderProvider userBuilderProvider) { sascha@1030: this.systemBuilderProvider = systemBuilderProvider; sascha@1030: this.userBuilderProvider = userBuilderProvider; sascha@1015: } sascha@1015: sascha@1015: public Builder getUserBuilder() { sascha@1030: return userBuilderProvider.getBuilder(); sascha@1015: } sascha@1015: sascha@1015: public Builder getSystemBuilder() { sascha@1030: return systemBuilderProvider.getBuilder(); sascha@1015: } sascha@1015: sascha@1015: protected static void artifactToParameters( sascha@1015: FLYSArtifact artifact, sascha@1015: Map parameters sascha@1015: ) { sascha@1015: parameters.put("current-state-id", artifact.getCurrentStateId()); sascha@1018: 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@1015: String key = sd.getName().replace('.', '-'); sascha@1015: parameters.put(key, value); sascha@1015: } sascha@1015: } sascha@1015: 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@1015: parameters.putAll(extraParameters); sascha@1015: } sascha@1015: sascha@1015: if (userId != null) { sascha@1015: parameters.put("user-id", userId); sascha@1015: } sascha@1015: sascha@1015: if (artifact != null) { sascha@1015: artifactToParameters(artifact, parameters); sascha@1015: } sascha@1015: sascha@1015: parameters.put("artifact-outs", outs); sascha@1015: sascha@1015: 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: felix@1029: if (userId != null) { // Use system and user templates. felix@1029: // Get connection to datacage db. sascha@1015: DataSource dataSource = DBConfig sascha@1015: .getInstance() sascha@1015: .getDBConnection() sascha@1015: .getDataSource(); sascha@1015: sascha@1015: Connection userConnection = dataSource.getConnection(); sascha@1015: try { sascha@1015: connections.add(new Builder.NamedConnection( sascha@1022: Builder.CONNECTION_USER, userConnection, false)); sascha@1018: sascha@1018: connections.add(new Builder.NamedConnection( sascha@1022: Builder.CONNECTION_SYSTEM, systemConnection, true)); sascha@1015: sascha@1030: getUserBuilder().build(connections, result, parameters); sascha@1015: } sascha@1015: finally { sascha@1015: userConnection.close(); sascha@1015: } sascha@1015: } felix@1029: else { // Use system template only. sascha@1015: connections.add(new Builder.NamedConnection( sascha@1022: Builder.CONNECTION_SYSTEM, systemConnection, true)); sascha@1015: sascha@1030: getSystemBuilder().build(connections, result, parameters); 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@1015: public static Recommendations createRecommendations( sascha@1015: File systemFile, sascha@1015: File userFile sascha@1015: ) { sascha@1015: log.debug("Recommendations.createBuilder"); sascha@1015: sascha@1015: if (!systemFile.isFile() || !systemFile.canRead()) { sascha@1015: log.error("Cannot open template file '" + systemFile + "'"); sascha@1015: return null; sascha@1015: } sascha@1015: sascha@1015: if (!userFile.isFile() || !userFile.canRead()) { sascha@1015: log.error("Cannot open template file '" + userFile + "'"); sascha@1015: return null; sascha@1015: } sascha@1015: sascha@1030: FileBuilderProvider ufbp = new FileBuilderProvider(userFile); sascha@1030: FileBuilderProvider sfbp = new FileBuilderProvider(systemFile); sascha@1030: sascha@1030: if (ufbp.getBuilder() == null || sfbp.getBuilder() == null) { sascha@1030: log.error("failed loading builder"); sascha@1015: return null; sascha@1015: } sascha@1030: sascha@1030: BuilderProvider ubp; sascha@1030: BuilderProvider sbp; sascha@1030: sascha@1030: if (DEVELOPMENT_MODE) { sascha@1030: ubp = ufbp; sascha@1030: sbp = sfbp; sascha@1030: } sascha@1030: else { sascha@1030: ubp = ufbp.toStaticProvider(); sascha@1030: sbp = sfbp.toStaticProvider(); sascha@1030: } sascha@1030: sascha@1030: return new Recommendations(sbp, ubp); sascha@1015: } sascha@1015: sascha@1015: protected static Recommendations createRecommendations() { sascha@1015: log.debug("Recommendations.createRecommendations"); sascha@1015: sascha@1015: String systemPath = Config.getStringXPath(XPATH_SYSTEM_TEMPLATE); sascha@1015: String userPath = Config.getStringXPath(XPATH_USER_TEMPLATE); sascha@1015: sascha@1015: if (systemPath == null || userPath == null) { sascha@1015: log.error("no path to template file given"); sascha@1015: return null; sascha@1015: } sascha@1015: sascha@1015: systemPath = Config.replaceConfigDir(systemPath); sascha@1015: userPath = Config.replaceConfigDir(userPath); sascha@1015: sascha@1015: return createRecommendations( sascha@1015: new File(systemPath), sascha@1015: new File(userPath)); sascha@1015: } sascha@1015: } sascha@1015: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :