Search in sources :

Example 46 with IOMessageImpl

use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.

the class AbstractBaseAlignmentLoader method generatePrefixMapping.

/**
 * Function to fill the prefixMapping and alignmentToInfo maps.
 *
 * @param addBase the URI of the new base alignment to add
 * @param projectLocation the project location or <code>null</code>
 * @param existingBases the map of existing bases
 * @param prefixMapping gets filled with a mapping from local to global
 *            prefixes
 * @param alignmentToInfo gets filled with a mapping from base alignment
 *            representations to prefixes and URIs
 * @param reporter the reporter
 * @return whether newBase actually is a new base and the add process should
 *         continue
 */
private boolean generatePrefixMapping(URI addBase, URI projectLocation, Map<String, URI> existingBases, Map<A, Map<String, String>> prefixMapping, Map<A, AlignmentInfo> alignmentToInfo, IOReporter reporter) {
    // Project location may be null if the project wasn't saved yet
    // Then, it still is okay, if all bases are absolute.
    URI currentAbsolute = projectLocation;
    URI usedAddBaseURI = addBase;
    URI absoluteAddBaseURI = resolve(currentAbsolute, usedAddBaseURI);
    // set of already seen URIs
    Set<URI> knownURIs = new HashSet<URI>();
    // reverse map of base
    Map<URI, String> uriToPrefix = new HashMap<URI, String>();
    // create URI to prefix map and known URIs
    for (Entry<String, URI> baseEntry : existingBases.entrySet()) {
        // make sure to use absolute URIs here for comparison
        URI absoluteBase = resolve(currentAbsolute, baseEntry.getValue());
        knownURIs.add(absoluteBase);
        uriToPrefix.put(absoluteBase, baseEntry.getKey());
    }
    if (uriToPrefix.containsKey(absoluteAddBaseURI)) {
        reporter.info(new IOMessageImpl("The base alignment (" + addBase + ") is already included.", null));
        return false;
    }
    Set<String> existingPrefixes = new HashSet<String>(existingBases.keySet());
    String newPrefix = generatePrefix(existingPrefixes);
    existingPrefixes.add(newPrefix);
    uriToPrefix.put(absoluteAddBaseURI, newPrefix);
    /*
		 * XXX Adding a base alignment could only use a PathUpdate for the
		 * movement of the base alignment which is not known in the current
		 * project. Maybe could try the one of the current project either way?
		 */
    // find all alignments to load (also missing ones) and load the beans
    LinkedList<URIPair> queue = new LinkedList<URIPair>();
    queue.add(new URIPair(absoluteAddBaseURI, usedAddBaseURI));
    while (!queue.isEmpty()) {
        URIPair baseURI = queue.pollFirst();
        A baseA;
        try {
            baseA = loadAlignment(new DefaultInputSupplier(baseURI.absoluteURI).getInput(), reporter);
        } catch (IOException e) {
            reporter.error(new IOMessageImpl("Couldn't load an included base alignment (" + baseURI.absoluteURI + ").", e));
            reporter.setSuccess(false);
            return false;
        }
        // add to alignment info map
        alignmentToInfo.put(baseA, new AlignmentInfo(uriToPrefix.get(baseURI.absoluteURI), baseURI));
        prefixMapping.put(baseA, new HashMap<String, String>());
        // load "missing" base alignments, too, add prefix mapping
        for (Entry<String, URI> baseEntry : getBases(baseA).entrySet()) {
            // rawURI may be relative
            URI rawURI = baseEntry.getValue();
            URI absoluteURI = baseURI.absoluteURI.resolve(rawURI);
            URI usedURI = absoluteURI;
            // and rawURI are relative, continue using a relative URI.
            if (!usedAddBaseURI.isAbsolute() && !baseURI.usedURI.isAbsolute() && !rawURI.isAbsolute()) {
                usedURI = IOUtils.getRelativePath(absoluteURI, currentAbsolute);
            }
            // check whether this base alignment is missing
            if (!knownURIs.contains(absoluteURI)) {
                reporter.info(new IOMessageImpl("A base alignment referenced another base alignment (" + absoluteURI + ") that was not yet known. It is now included, too.", null));
                queue.add(new URIPair(absoluteURI, usedURI));
                knownURIs.add(absoluteURI);
                String prefix = generatePrefix(existingPrefixes);
                existingPrefixes.add(prefix);
                uriToPrefix.put(absoluteURI, prefix);
            }
            // add prefix mapping
            prefixMapping.get(baseA).put(baseEntry.getKey(), uriToPrefix.get(absoluteURI));
        }
    }
    return true;
}
Also used : DefaultInputSupplier(eu.esdihumboldt.hale.common.core.io.supplier.DefaultInputSupplier) HashMap(java.util.HashMap) IOMessageImpl(eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl) IOException(java.io.IOException) URI(java.net.URI) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet)

Example 47 with IOMessageImpl

use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.

the class AbstractBaseAlignmentLoader method processBaseAlignments.

/**
 * Creates and adds cells and modifiers of the base alignments to the main
 * alignment.
 *
 * @param alignment the alignment to add base alignments to
 * @param sourceTypes the source types to use for resolving definition
 *            references
 * @param targetTypes the target types to use for resolving definition
 *            references
 * @param prefixMapping gets filled with a mapping from local to global
 *            prefixes
 * @param alignmentToInfo gets filled with a mapping from base alignment
 *            representations to prefixes and URIs
 * @param reporter the I/O reporter to report any errors to, may be
 *            <code>null</code>
 * @throws IOException if one of the base alignments does not have cell ids
 */
private void processBaseAlignments(MutableAlignment alignment, TypeIndex sourceTypes, TypeIndex targetTypes, Map<A, Map<String, String>> prefixMapping, Map<A, AlignmentInfo> alignmentToInfo, IOReporter reporter) throws IOException {
    for (Entry<A, AlignmentInfo> base : alignmentToInfo.entrySet()) {
        Collection<C> baseCells = getCells(base.getKey());
        boolean hasIds = true;
        for (C baseCell : baseCells) if (Strings.isNullOrEmpty(getCellId(baseCell))) {
            hasIds = false;
            break;
        }
        if (!hasIds) {
            throw new IOException("At least one base alignment (" + base.getValue().uri.absoluteURI + ") has no cell ids. Please load and save it to generate them.");
        }
    }
    for (Entry<A, AlignmentInfo> base : alignmentToInfo.entrySet()) {
        if (alignment.getBaseAlignments().containsValue(base.getValue().uri.usedURI)) {
            // base alignment already present
            // can currently happen with base alignments included in base
            // alignments
            reporter.warn(new IOMessageImpl("Base alignment at " + base.getValue().uri.usedURI + " has already been added", null));
        } else {
            Collection<CustomPropertyFunction> baseFunctions = getPropertyFunctions(base.getKey(), sourceTypes, targetTypes);
            Collection<C> baseCells = getCells(base.getKey());
            Collection<BaseAlignmentCell> createdBaseCells = new ArrayList<BaseAlignmentCell>(baseCells.size());
            List<MutableCell> createdCells = new ArrayList<>(baseCells.size());
            for (C baseCell : baseCells) {
                // add cells of base alignments
                MutableCell cell = createCell(baseCell, sourceTypes, targetTypes, reporter);
                if (cell != null) {
                    createdCells.add(cell);
                }
            }
            // Migrate UnmigratedCells
            migrateCells(createdCells, reporter);
            for (MutableCell cell : createdCells) {
                createdBaseCells.add(new BaseAlignmentCell(cell, base.getValue().uri.usedURI, base.getValue().prefix));
            }
            alignment.addBaseAlignment(base.getValue().prefix, base.getValue().uri.usedURI, createdBaseCells, baseFunctions);
        }
    }
    // add modifiers of base alignments
    for (Entry<A, AlignmentInfo> base : alignmentToInfo.entrySet()) applyModifiers(alignment, getModifiers(base.getKey()), prefixMapping.get(base.getKey()), base.getValue().prefix, true, reporter);
}
Also used : MutableCell(eu.esdihumboldt.hale.common.align.model.MutableCell) IOMessageImpl(eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl) ArrayList(java.util.ArrayList) IOException(java.io.IOException) BaseAlignmentCell(eu.esdihumboldt.hale.common.align.model.BaseAlignmentCell) CustomPropertyFunction(eu.esdihumboldt.hale.common.align.extension.function.custom.CustomPropertyFunction)

Example 48 with IOMessageImpl

use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.

the class MappingExporter method execute.

@Override
protected IOReport execute(ProgressIndicator progress, IOReporter reporter) throws IOProviderConfigurationException, IOException {
    progress.begin("Generate mapping documentation", ProgressIndicator.UNKNOWN);
    // retrieve template URL
    URL templateUrl = getClass().getResource("mapping.html");
    // generate Json representation
    CellJsonExtension ext = new ExtendedCellRepresentation(getAlignment(), getServiceProvider());
    ValueRepresentation rep = new JsonValueRepresentation();
    StringWriter jsonWriter = new StringWriter();
    JsonStreamBuilder json = new JsonStreamBuilder(jsonWriter, true);
    Set<Locale> locales = AlignmentJson.alignmentInfoJSON(getAlignment(), json, getServiceProvider(), getProjectInfo(), ext, rep, Locale.getDefault(), getSourceSchema(), getTargetSchema());
    // create language binding
    String languageJson = getLanguageJson(locales);
    // create template binding
    Map<String, Object> binding = new HashMap<>();
    binding.put("json", jsonWriter.toString());
    String title = (getProjectInfo() != null && getProjectInfo().getName() != null) ? getProjectInfo().getName() : "Mapping documentation";
    binding.put("title", title);
    binding.put("languages", languageJson);
    binding.put("halejsVersion", HALEJS_VERSION);
    // initialize template engine
    GStringTemplateEngine engine = new GStringTemplateEngine();
    // bind and write template
    try (Writer out = new OutputStreamWriter(getTarget().getOutput(), StandardCharsets.UTF_8)) {
        Writable template = engine.createTemplate(templateUrl).make(binding);
        template.writeTo(out);
        reporter.setSuccess(true);
    } catch (Exception e) {
        reporter.error(new IOMessageImpl("Error creating mapping documentation", e));
        reporter.setSuccess(false);
    } finally {
        progress.end();
    }
    return reporter;
}
Also used : Locale(java.util.Locale) JsonValueRepresentation(eu.esdihumboldt.hale.io.html.svg.mapping.json.JsonValueRepresentation) HashMap(java.util.HashMap) ExtendedCellRepresentation(eu.esdihumboldt.hale.io.html.svg.mapping.json.ExtendedCellRepresentation) IOMessageImpl(eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl) Writable(groovy.lang.Writable) GStringTemplateEngine(groovy.text.GStringTemplateEngine) CellJsonExtension(eu.esdihumboldt.hale.io.html.svg.mapping.json.CellJsonExtension) URL(java.net.URL) IOProviderConfigurationException(eu.esdihumboldt.hale.common.core.io.IOProviderConfigurationException) IOException(java.io.IOException) ValueRepresentation(eu.esdihumboldt.hale.io.html.svg.mapping.json.ValueRepresentation) JsonValueRepresentation(eu.esdihumboldt.hale.io.html.svg.mapping.json.JsonValueRepresentation) StringWriter(java.io.StringWriter) JsonStreamBuilder(eu.esdihumboldt.util.groovy.json.JsonStreamBuilder) OutputStreamWriter(java.io.OutputStreamWriter) OutputStreamWriter(java.io.OutputStreamWriter) StringWriter(java.io.StringWriter) Writer(java.io.Writer) AbstractAlignmentWriter(eu.esdihumboldt.hale.common.align.io.impl.AbstractAlignmentWriter)

Example 49 with IOMessageImpl

use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.

the class JDBCInstanceReader method execute.

@Override
protected IOReport execute(ProgressIndicator progress, IOReporter reporter) throws IOProviderConfigurationException, IOException {
    progress.begin("Configure database connection", ProgressIndicator.UNKNOWN);
    try {
        testConnection();
        String user = getParameter(PARAM_USER).as(String.class);
        String password = getParameter(PARAM_PASSWORD).as(String.class);
        Map<TypeDefinition, InstanceCollection> collections = new HashMap<>();
        // only load instances for mapping relevant types
        for (TypeDefinition type : getSourceSchema().getMappingRelevantTypes()) {
            // check constraint if a Database table or not
            if (type.getConstraint(DatabaseTable.class).isTable()) {
                collections.put(type, new JDBCTableCollection(type, getSource().getLocation(), user, password, getCrsProvider(), getServiceProvider()) {

                    // To provide extensibility for getting customized
                    // database connection for
                    // Instance reading.
                    @Override
                    protected Connection createConnection() throws SQLException {
                        return JDBCInstanceReader.this.getConnection();
                    }
                });
            } else // database?
            if (type.getConstraint(SQLQuery.class).hasQuery()) {
                collections.put(type, new JDBCTableCollection(type, getSource().getLocation(), user, password, getCrsProvider(), getServiceProvider()) {

                    // To provide extensibility for getting customized
                    // database connection for
                    // Instance reading.
                    @Override
                    protected Connection createConnection() throws SQLException {
                        return JDBCInstanceReader.this.getConnection();
                    }
                });
            }
        }
        collection = new PerTypeInstanceCollection(collections);
        reporter.setSuccess(true);
    } catch (Exception e) {
        reporter.error(new IOMessageImpl("Error configuring database connection", e));
        reporter.setSuccess(false);
    } finally {
        progress.end();
    }
    return reporter;
}
Also used : HashMap(java.util.HashMap) SQLException(java.sql.SQLException) MultiInstanceCollection(eu.esdihumboldt.hale.common.instance.model.impl.MultiInstanceCollection) InstanceCollection(eu.esdihumboldt.hale.common.instance.model.InstanceCollection) PerTypeInstanceCollection(eu.esdihumboldt.hale.common.instance.model.ext.impl.PerTypeInstanceCollection) Connection(java.sql.Connection) IOMessageImpl(eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl) IOProviderConfigurationException(eu.esdihumboldt.hale.common.core.io.IOProviderConfigurationException) SQLSyntaxErrorException(java.sql.SQLSyntaxErrorException) IOException(java.io.IOException) SQLException(java.sql.SQLException) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) DatabaseTable(eu.esdihumboldt.hale.io.jdbc.constraints.DatabaseTable) PerTypeInstanceCollection(eu.esdihumboldt.hale.common.instance.model.ext.impl.PerTypeInstanceCollection)

Example 50 with IOMessageImpl

use of eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl in project hale by halestudio.

the class JDBCInstanceWriter method populateInsertStatementOrExecuteAutoIncStatement.

/**
 * Populate a prepared insert statement with values from the given instance.
 * Checks if the property has auto incremental constraint, if it has then it
 * maps the original old id to the id that is auto incremented while
 * inserting the value. This mapping is used when inserting the foreign key
 * values associated with those auto incremented column ids whose value has
 * been changed. Thus, insertion of the foreign key wont fail. It will
 * either execute the statement directly or add it into the batches
 * depending upon the auto incremented flag.
 *
 * @param statement the insert statement
 * @param properties the properties to fill the statement with
 * @param instance the instance
 * @param reporter the reporter
 * @param conn Connection (used for Geometry conversion for oracle)
 * @throws SQLException if configuring the statement fails
 */
private void populateInsertStatementOrExecuteAutoIncStatement(PreparedStatement statement, Set<QName> properties, Instance instance, IOReporter reporter, Connection conn) throws SQLException {
    TypeDefinition type = instance.getDefinition();
    int index = 1;
    Object oldValue = null;
    boolean isAutoIncremented = false;
    for (QName propertyName : properties) {
        PropertyDefinition property = (PropertyDefinition) type.getChild(propertyName);
        Object[] values = instance.getProperty(propertyName);
        SQLType sqlType = property.getPropertyType().getConstraint(SQLType.class);
        if (!sqlType.isSet()) {
            reporter.error(new IOMessageImpl("SQL type not set. Please only export to schemas read from a database.", null));
            statement.setObject(index, null);
            continue;
        }
        SQLArray arrayInfo = property.getPropertyType().getConstraint(SQLArray.class);
        Object value;
        if (arrayInfo.isArray() && arrayInfo.getDimension() <= 1) {
            // array as multiple occurrence property
            value = (values == null) ? (new Object[0]) : (values);
        } else {
            // single value
            if (values != null && values.length > 1)
                reporter.warn(new IOMessageImpl("Multiple values for a property. Only exporting first.", null));
            value = (values == null || values.length == 0) ? null : values[0];
        }
        AutoGenerated auto = property.getConstraint(AutoGenerated.class);
        if (!isWriteUnordered()) {
            if (auto.isEnabled()) {
                isAutoIncremented = true;
                if (value != null) {
                    oldValue = value;
                }
                continue;
            }
        }
        Reference ref = property.getConstraint(Reference.class);
        if (ref.getReferencedTypes() != null) {
            TypeDefinition td = (TypeDefinition) ref.getReferencedTypes().toArray()[0];
            Map<Object, Long> marshMallow = typAuto.get(td);
            if (marshMallow != null && value != null) {
                // lookup identifier for reference
                value = marshMallow.get(processLookupId(value));
            }
        }
        if (values == null || values.length == 0) {
            // XXX The default value could be a function call.
            // Better would be to leave the column out of the insert
            // statement, or set it to the SQL keyword "DEFAULT".
            DefaultValue defaultValue = property.getConstraint(DefaultValue.class);
            if (defaultValue.isSet())
                statement.setObject(index, defaultValue.getValue(), sqlType.getType());
            else if (property.getConstraint(NillableFlag.class).isEnabled())
                statement.setNull(index, sqlType.getType());
            else {
                // no default, not nillable, will not work...
                // set it to null here and let query fail (probably)
                // XXX maybe skip this insert?
                statement.setNull(index, sqlType.getType());
                reporter.warn(new IOMessageImpl("Property no value, not nillable, no default value, insert will probably fail.", null));
            }
        } else if (value == null)
            statement.setNull(index, sqlType.getType());
        else
            setStatementParameter(statement, index, value, property, sqlType.getType(), reporter, conn);
        index++;
    }
    if (isAutoIncremented) {
        statement.execute();
        ResultSet rs = statement.getGeneratedKeys();
        Long newValue = null;
        while (rs.next()) {
            newValue = rs.getLong(1);
        }
        addIDMapping(type, oldValue, newValue);
    } else {
        statement.addBatch();
    }
}
Also used : QName(javax.xml.namespace.QName) Reference(eu.esdihumboldt.hale.common.schema.model.constraint.property.Reference) IOMessageImpl(eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition) GeometryAdvisorConstraint(eu.esdihumboldt.hale.io.jdbc.constraints.internal.GeometryAdvisorConstraint) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) DefaultValue(eu.esdihumboldt.hale.io.jdbc.constraints.DefaultValue) ResultSet(java.sql.ResultSet) AutoGenerated(eu.esdihumboldt.hale.common.schema.model.constraint.property.AutoGenerated) SQLType(eu.esdihumboldt.hale.io.jdbc.constraints.SQLType) SQLArray(eu.esdihumboldt.hale.io.jdbc.constraints.SQLArray)

Aggregations

IOMessageImpl (eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl)85 IOException (java.io.IOException)43 IOProviderConfigurationException (eu.esdihumboldt.hale.common.core.io.IOProviderConfigurationException)33 QName (javax.xml.namespace.QName)20 URI (java.net.URI)15 TypeDefinition (eu.esdihumboldt.hale.common.schema.model.TypeDefinition)14 InputStream (java.io.InputStream)13 File (java.io.File)12 HashMap (java.util.HashMap)11 DefaultInputSupplier (eu.esdihumboldt.hale.common.core.io.supplier.DefaultInputSupplier)9 FileOutputStream (java.io.FileOutputStream)9 ArrayList (java.util.ArrayList)9 IOReport (eu.esdihumboldt.hale.common.core.io.report.IOReport)8 OutputStream (java.io.OutputStream)8 InstanceCollection (eu.esdihumboldt.hale.common.instance.model.InstanceCollection)7 XmlElement (eu.esdihumboldt.hale.io.xsd.model.XmlElement)7 DefaultTypeDefinition (eu.esdihumboldt.hale.common.schema.model.impl.DefaultTypeDefinition)6 MutableCell (eu.esdihumboldt.hale.common.align.model.MutableCell)5 PathUpdate (eu.esdihumboldt.hale.common.core.io.PathUpdate)4 Value (eu.esdihumboldt.hale.common.core.io.Value)4