org.deegree.console.featurestore.MappingWizardSQL.java Source code

Java tutorial

Introduction

Here is the source code for org.deegree.console.featurestore.MappingWizardSQL.java

Source

//$HeadURL$
/*----------------------------------------------------------------------------
 This file is part of deegree, http://deegree.org/
 Copyright (C) 2001-2011 by:
 - Department of Geography, University of Bonn -
 and
 - lat/lon GmbH -
    
 This library is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free
 Software Foundation; either version 2.1 of the License, or (at your option)
 any later version.
 This library is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 details.
 You should have received a copy of the GNU Lesser General Public License
 along with this library; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 Contact information:
    
 lat/lon GmbH
 Aennchenstr. 19, 53177 Bonn
 Germany
 http://lat-lon.de/
    
 Department of Geography, University of Bonn
 Prof. Dr. Klaus Greve
 Postfach 1147, 53001 Bonn
 Germany
 http://www.geographie.uni-bonn.de/deegree/
    
 e-mail: info@deegree.org
 ----------------------------------------------------------------------------*/
package org.deegree.console.featurestore;

import static javax.faces.application.FacesMessage.SEVERITY_ERROR;
import static org.deegree.feature.types.property.GeometryPropertyType.CoordinateDimension.DIM_2;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;

import org.apache.commons.io.IOUtils;
import org.deegree.client.core.utils.SQLExecution;
import org.deegree.commons.config.DeegreeWorkspace;
import org.deegree.commons.config.ResourceState;
import org.deegree.commons.config.ResourceState.StateType;
import org.deegree.commons.jdbc.ConnectionManager;
import org.deegree.commons.jdbc.ConnectionManager.Type;
import org.deegree.commons.utils.FileUtils;
import org.deegree.commons.xml.stax.IndentingXMLStreamWriter;
import org.deegree.console.Config;
import org.deegree.console.ConfigManager;
import org.deegree.console.WorkspaceBean;
import org.deegree.cs.persistence.CRSManager;
import org.deegree.cs.refs.coordinatesystem.CRSRef;
import org.deegree.feature.persistence.FeatureStoreManager;
import org.deegree.feature.persistence.sql.GeometryStorageParams;
import org.deegree.feature.persistence.sql.MappedAppSchema;
import org.deegree.feature.persistence.sql.SQLFeatureStore;
import org.deegree.feature.persistence.sql.config.SQLFeatureStoreConfigWriter;
import org.deegree.feature.persistence.sql.ddl.DDLCreator;
import org.deegree.feature.persistence.sql.mapper.AppSchemaMapper;
import org.deegree.feature.types.AppSchema;
import org.deegree.gml.schema.GMLAppSchemaReader;
import org.deegree.sqldialect.SQLDialect;
import org.deegree.sqldialect.SQLDialectManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * JSF bean that helps with creating configurations for the {@link SQLFeatureStore}.
 * 
 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
 * @author last edited by: $Author$
 * 
 * @version $Revision$, $Date$
 */
@ManagedBean
@SessionScoped
public class MappingWizardSQL {

    private static transient Logger LOG = LoggerFactory.getLogger(MappingWizardSQL.class);

    private String jdbcId;

    private String wizardMode = "template";

    private String storageMode = "blob";

    private String[] selectedAppSchemaFiles = new String[0];

    private AppSchema appSchema;

    private AppSchemaInfo appSchemaInfo;

    private MappedAppSchema mappedSchema;

    private String storageCrs = "EPSG:4326";

    private String storageSrid = "-1";

    private Integer columnNameLength = 16;

    private Integer tableNameLength = 16;

    private Type connectionType;

    private ResourceState resourceState;

    public String getFeatureStoreId() throws ClassNotFoundException, SecurityException, NoSuchMethodException,
            IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
        ConfigManager mgr = (ConfigManager) ctx.getSessionMap().get("configManager");
        return mgr.getNewConfigId();
    }

    private DeegreeWorkspace getWorkspace() {
        ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
        DeegreeWorkspace ws = ((WorkspaceBean) ctx.getApplicationMap().get("workspace")).getActiveWorkspace();
        return ws;
    }

    public SortedSet<String> getAvailableJdbcConns() {
        ConnectionManager mgr = getWorkspace().getSubsystemManager(ConnectionManager.class);
        SortedSet<String> conns = new TreeSet<String>();
        for (ResourceState<?> rs : mgr.getStates()) {
            // TODO remove this hack
            if (rs.getId().equals("LOCK_DB")) {
                continue;
            }
            if (rs.getType().equals(StateType.init_ok)) {
                conns.add(rs.getId());
            }
        }
        return conns;
    }

    public String getSelectedJdbcConn() {
        return jdbcId;
    }

    public void setSelectedJdbcConn(String jdbcId) {
        this.jdbcId = jdbcId;
        ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
        DeegreeWorkspace ws = ((WorkspaceBean) ctx.getApplicationMap().get("workspace")).getActiveWorkspace();
        ConnectionManager mgr = ws.getSubsystemManager(ConnectionManager.class);
        this.connectionType = mgr.getType(jdbcId);
        SQLDialectManager dialectMgr = ws.getSubsystemManager(SQLDialectManager.class);
        if (dialectMgr != null) {
            try {
                SQLDialect dialect = dialectMgr.create(jdbcId);
                columnNameLength = dialect.getMaxColumnNameLength();
                tableNameLength = dialect.getMaxTableNameLength();
                storageSrid = dialect.getUndefinedSrid();
            } catch (Throwable t) {
                FacesMessage fm = new FacesMessage(SEVERITY_ERROR, "SQLDialect error: " + t.getMessage(), null);
                FacesContext.getCurrentInstance().addMessage(null, fm);
            }
        }
    }

    public String getMode() {
        return wizardMode;
    }

    public void setMode(String mode) {
        this.wizardMode = mode;
    }

    public File getAppSchemaDirectory() throws IOException {
        ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
        DeegreeWorkspace ws = ((WorkspaceBean) ctx.getApplicationMap().get("workspace")).getActiveWorkspace();
        File appSchemaDirectory = new File(ws.getLocation(), "appschemas");
        return appSchemaDirectory;
    }

    public TreeSet<String> getAvailableAppSchemaFiles() throws IOException {
        List<File> files = FileUtils.findFilesForExtensions(getAppSchemaDirectory(), true, "xsd");
        TreeSet<String> fileNames = new TreeSet<String>();
        String appDirFileName = getAppSchemaDirectory().getCanonicalPath();
        for (File file : files) {
            String canonicalFileName = file.getCanonicalPath();
            if (canonicalFileName.startsWith(appDirFileName)) {
                fileNames.add(canonicalFileName.substring(appDirFileName.length()));
            }
        }
        return fileNames;
    }

    public String[] getSelectedAppSchemaFiles() {
        return selectedAppSchemaFiles;
    }

    public void setSelectedAppSchemaFiles(String[] files) {
        this.selectedAppSchemaFiles = files;
    }

    public String getGmlVersion() {
        return appSchema.getGMLSchema().getVersion().name();
    }

    public AppSchemaInfo getAppSchemaInfo() {
        return appSchemaInfo;
    }

    public String getStorageMode() {
        return storageMode;
    }

    public void setStorageMode(String storageMode) {
        this.storageMode = storageMode;
    }

    public String getStorageCrs() {
        return storageCrs;
    }

    public void setStorageCrs(String storageCrs) {
        this.storageCrs = storageCrs;
    }

    public String getStorageSrid() {
        return storageSrid;
    }

    public void setStorageSrid(String storageSrid) {
        this.storageSrid = storageSrid;
    }

    public String selectMode() {
        if ("template".equals(wizardMode)) {
            return "/console/jsf/wizard";
        } else if ("schema".equals(wizardMode)) {
            return "/console/featurestore/sql/wizard2";
        }
        return "/console/jsf/wizard";
    }

    public String analyzeSchema() throws IOException, ClassNotFoundException, SecurityException,
            NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {

        if (selectedAppSchemaFiles.length == 0) {
            FacesMessage fm = new FacesMessage(SEVERITY_ERROR, "At least one schema file must be selected.", null);
            FacesContext.getCurrentInstance().addMessage(null, fm);
            return null;
        }

        String[] schemaUrls = new String[selectedAppSchemaFiles.length];
        int i = 0;
        for (String schemaFile : selectedAppSchemaFiles) {
            File fullFile = new File(getAppSchemaDirectory(), schemaFile);
            URL schemaUrl = fullFile.toURI().toURL();
            schemaUrls[i++] = schemaUrl.toString();
        }

        try {
            GMLAppSchemaReader xsdDecoder = new GMLAppSchemaReader(null, null, schemaUrls);
            appSchema = xsdDecoder.extractAppSchema();
            appSchemaInfo = new AppSchemaInfo(appSchema);
        } catch (Throwable t) {
            String msg = "Unable to parse GML application schema.";
            FacesMessage fm = new FacesMessage(SEVERITY_ERROR, msg, t.getMessage());
            FacesContext.getCurrentInstance().addMessage(null, fm);
        }
        return "/console/featurestore/sql/wizard3";
    }

    public String generateConfig() {

        try {
            ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
            DeegreeWorkspace ws = ((WorkspaceBean) ctx.getApplicationMap().get("workspace")).getActiveWorkspace();

            CRSRef storageCrs = CRSManager.getCRSRef(this.storageCrs);
            boolean createBlobMapping = storageMode.equals("hybrid") || storageMode.equals("blob");
            boolean createRelationalMapping = storageMode.equals("hybrid") || storageMode.equals("relational");
            GeometryStorageParams geometryParams = new GeometryStorageParams(storageCrs, storageSrid, DIM_2);
            AppSchemaMapper mapper = new AppSchemaMapper(appSchema, createBlobMapping, createRelationalMapping,
                    geometryParams, Math.min(tableNameLength, columnNameLength), true, false);
            mappedSchema = mapper.getMappedSchema();
            SQLFeatureStoreConfigWriter configWriter = new SQLFeatureStoreConfigWriter(mappedSchema);
            File tmpConfigFile = File.createTempFile("fsconfig", ".xml");
            FileOutputStream fos = new FileOutputStream(tmpConfigFile);
            XMLStreamWriter xmlWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(fos);
            xmlWriter = new IndentingXMLStreamWriter(xmlWriter);

            List<String> schemaUrls = new ArrayList<String>(selectedAppSchemaFiles.length);
            for (String schemaFile : selectedAppSchemaFiles) {
                schemaUrls.add(".." + File.separator + ".." + File.separator + "appschemas" + schemaFile);
            }
            configWriter.writeConfig(xmlWriter, jdbcId, schemaUrls);
            xmlWriter.close();
            IOUtils.closeQuietly(fos);
            System.out.println("Wrote to file " + tmpConfigFile);

            // let the resource manager do the dirty work

            ConfigManager mgr = (ConfigManager) ctx.getSessionMap().get("configManager");

            // let the resource manager do the dirty work
            try {
                FeatureStoreManager fsMgr = ws.getSubsystemManager(FeatureStoreManager.class);
                this.resourceState = fsMgr.createResource(getFeatureStoreId(), new FileInputStream(tmpConfigFile));
                Config c = new Config(this.resourceState, mgr, fsMgr, "/console/featurestore/sql/wizard4", false);
                return c.edit();
            } catch (Throwable t) {
                LOG.error(t.getMessage(), t);
                FacesMessage fm = new FacesMessage(SEVERITY_ERROR, "Unable to create config: " + t.getMessage(),
                        null);
                FacesContext.getCurrentInstance().addMessage(null, fm);
                return null;
            }
        } catch (Throwable t) {
            LOG.error(t.getMessage(), t);
            String msg = "Error generating feature store configuration.";
            FacesMessage fm = new FacesMessage(SEVERITY_ERROR, msg, t.getMessage());
            FacesContext.getCurrentInstance().addMessage(null, fm);
            return "/console/featurestore/sql/wizard3";
        }
    }

    public String createTables() {
        ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
        DeegreeWorkspace ws = ((WorkspaceBean) ctx.getApplicationMap().get("workspace")).getActiveWorkspace();
        FeatureStoreManager fsMgr = ws.getSubsystemManager(FeatureStoreManager.class);
        resourceState = fsMgr.activate(resourceState.getId());
        SQLFeatureStore store = (SQLFeatureStore) resourceState.getResource();
        String[] createStmts = DDLCreator.newInstance(store.getSchema(), store.getDialect()).getDDL();
        resourceState = fsMgr.deactivate(resourceState.getId());
        SQLExecution execution = new SQLExecution(jdbcId, createStmts, "/console/featurestore/sql/wizard5", ws);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("execution", execution);
        return "/console/generic/sql.jsf?faces-redirect=true";
    }

    public void setColumnNameLength(Integer columnNameLength) {
        this.columnNameLength = columnNameLength;
    }

    public Integer getColumnNameLength() {
        return columnNameLength;
    }

    public void setTableNameLength(Integer tableNameLength) {
        this.tableNameLength = tableNameLength;
    }

    public Integer getTableNameLength() {
        return tableNameLength;
    }

    public String activateFS() {
        try {
            ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
            WorkspaceBean workspaceBean = (WorkspaceBean) ctx.getApplicationMap().get("workspace");
            DeegreeWorkspace ws = workspaceBean.getActiveWorkspace();
            FeatureStoreManager fsMgr = ws.getSubsystemManager(FeatureStoreManager.class);
            fsMgr.activate(getFeatureStoreId());
            workspaceBean.setModified();
        } catch (Throwable t) {
            t.printStackTrace();
            String msg = "Error activating new feature store";
            FacesMessage fm = new FacesMessage(SEVERITY_ERROR, msg, t.getMessage());
            FacesContext.getCurrentInstance().addMessage(null, fm);
            return null;
        }
        return "/console/featurestore/buttons";
    }
}