/* * Copyright (c) 2013 Fraunhofer IGD * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Fraunhofer IGD */ package eu.esdihumboldt.hale.app.bgis.ade.duplicate; import java.io.IOException; import java.io.InputStream; import java.text.MessageFormat; import java.util.Date; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.core.runtime.content.IContentType; import com.google.common.collect.HashMultimap; import com.google.common.collect.SetMultimap; import eu.esdihumboldt.hale.app.bgis.ade.common.BGISAppConstants; import eu.esdihumboldt.hale.app.bgis.ade.common.BGISAppUtil; import eu.esdihumboldt.hale.common.align.io.AlignmentWriter; import eu.esdihumboldt.hale.common.align.model.Alignment; import eu.esdihumboldt.hale.common.align.model.Cell; import eu.esdihumboldt.hale.common.align.model.CellUtil; import eu.esdihumboldt.hale.common.align.model.EntityDefinition; import eu.esdihumboldt.hale.common.align.model.MutableAlignment; import eu.esdihumboldt.hale.common.align.model.MutableCell; import eu.esdihumboldt.hale.common.align.model.impl.DefaultAlignment; import eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition; import eu.esdihumboldt.hale.common.core.HalePlatform; import eu.esdihumboldt.hale.common.core.io.HaleIO; import eu.esdihumboldt.hale.common.core.io.extension.IOProviderDescriptor; import eu.esdihumboldt.hale.common.core.io.impl.NullProgressIndicator; import eu.esdihumboldt.hale.common.core.io.report.IOReport; import eu.esdihumboldt.hale.common.core.io.supplier.DefaultInputSupplier; import eu.esdihumboldt.hale.common.core.io.supplier.FileIOSupplier; import eu.esdihumboldt.hale.common.core.io.supplier.LocatableInputSupplier; import eu.esdihumboldt.hale.common.core.report.Report; import eu.esdihumboldt.hale.common.core.report.ReportHandler; import eu.esdihumboldt.hale.common.headless.impl.ProjectTransformationEnvironment; import eu.esdihumboldt.hale.common.schema.SchemaSpaceID; import eu.esdihumboldt.hale.common.schema.model.PropertyDefinition; import eu.esdihumboldt.hale.common.schema.model.SchemaSpace; import eu.esdihumboldt.hale.common.schema.model.TypeDefinition; /** * Generates an extended mappings for BGIS CityGML ADE based on an example * mapping. * * @author Simon Templer */ public class GenerateDuplicates implements BGISAppConstants { private SchemaSpace sourceSchema; private SchemaSpace targetSchema; private Alignment examples; private Alignment alignment; private GenerateDuplicatesContext context; /** * Generate the default value mapping based on the given configuration. * * @param context the configuration for the mapping generation * @throws Exception if an unrecoverable error occurs during the generation */ public void generate(GenerateDuplicatesContext context) throws Exception { this.context = context; // load project if (loadProject()) { // generate mapping generateMapping(); // write alignment writeAlignment(); } } private boolean loadProject() throws IOException { final AtomicBoolean success = new AtomicBoolean(true); LocatableInputSupplier<? extends InputStream> projectIn = new DefaultInputSupplier( context.getProject()); ProjectTransformationEnvironment env = new ProjectTransformationEnvironment("sample", projectIn, new ReportHandler() { @Override public void publishReport(Report<?> report) { if (report.isSuccess() && report.getErrors().isEmpty()) { System.out.println(report.getSummary()); } else { System.err.println("Error loading project: " + report.getSummary()); success.set(false); } } }); if (success.get()) { this.sourceSchema = env.getSourceSchema(); this.targetSchema = env.getTargetSchema(); this.examples = env.getAlignment(); return true; } return false; } private void generateMapping() { System.out.println("Indexing example cells..."); // index all cells based on the target property name SetMultimap<String, Cell> exampleCells = HashMultimap.create(); for (Cell cell : examples.getCells()) { if (cell.getTarget().size() == 1) { // only supports cells with one target EntityDefinition entityDef = CellUtil.getFirstEntity(cell.getTarget()) .getDefinition(); if (entityDef.getDefinition() instanceof PropertyDefinition) { if (ADE_NS.equals(entityDef.getDefinition().getName().getNamespaceURI())) { exampleCells.put(entityDef.getDefinition().getName().getLocalPart(), cell); } else System.out.println("WARNING: ignoring cell with non-ADE target property"); } else System.out.println("WARNING: ignoring type cell"); } else System.out.println("WARNING: ignoring cell with multiple or no targets"); } // collect all ADE feature types List<TypeDefinition> featureTypes = BGISAppUtil.getADEFeatureTypes(targetSchema); // visit ADE properties and create cells System.out.println("Generating mapping from example cells for"); String cellNote = MessageFormat.format( "Generated through duplication of example cells on BGIS ADE feature types.\n" + "{0,date,medium}", new Date()); DuplicateVisitor visitor = new DuplicateVisitor(exampleCells, cellNote); for (TypeDefinition type : featureTypes) { System.out.println(type.getDisplayName() + "..."); visitor.accept(new TypeEntityDefinition(type, SchemaSpaceID.TARGET, null)); } if (visitor.getCells().isEmpty()) { System.out.println("WARNING: no cells were created"); } else { System.out.println(visitor.getCells().size() + " cells were created."); } // create alignment MutableAlignment align = new DefaultAlignment(); for (MutableCell cell : visitor.getCells()) { align.addCell(cell); } this.alignment = align; } private void writeAlignment() throws Exception { System.out.println("Writing alignment to " + context.getOut().getAbsolutePath()); // create alignment writer IContentType contentType = HalePlatform.getContentTypeManager().getContentType( ALIGNMENT_CONTENT_TYPE); IOProviderDescriptor factory = HaleIO.findIOProviderFactory(AlignmentWriter.class, contentType, null); AlignmentWriter writer = (AlignmentWriter) factory.createExtensionObject(); // configure alignment writer writer.setSourceSchema(sourceSchema); writer.setTargetSchema(targetSchema); writer.setTarget(new FileIOSupplier(context.getOut())); writer.setAlignment(alignment); IOReport report = writer.execute(new NullProgressIndicator()); if (!report.isSuccess() || !report.getErrors().isEmpty()) { throw new IllegalStateException("Errors while writing the alignment."); } else { System.out.println("Completed successfully."); } } }