package com.ximple.eofms.jobs.context.edbgeo; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.transaction.util.CommonsLoggingLogger; import org.apache.commons.transaction.util.LoggerFacade; import org.geotools.data.DataStore; import org.geotools.data.Transaction; import org.geotools.data.jdbc.JDBCUtils; import org.opengis.feature.IllegalAttributeException; import org.geotools.feature.SchemaException; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.feature.type.FeatureTypeImpl; import org.geotools.geometry.jts.JTSFactoryFinder; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import com.edb.util.PSQLException; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.ximple.eofms.util.DefaultColorTable; import com.ximple.eofms.util.FeatureTypeBuilderUtil; import com.ximple.eofms.util.GeometryConverterDecorator; import com.ximple.io.dgn7.ArcElement; import com.ximple.io.dgn7.ComplexChainElement; import com.ximple.io.dgn7.Element; import com.ximple.io.dgn7.EllipseElement; import com.ximple.io.dgn7.FrammeAttributeData; import com.ximple.io.dgn7.LineElement; import com.ximple.io.dgn7.LineStringElement; import com.ximple.io.dgn7.ShapeElement; import com.ximple.io.dgn7.TextElement; import com.ximple.io.dgn7.TextNodeElement; import com.ximple.io.dgn7.UserAttributeData; public class GeneralDgnConvertEdbGeoJobContext extends AbstractDgnToEdbGeoJobContext { static final Log logger = LogFactory.getLog(GeneralDgnConvertEdbGeoJobContext.class); static final LoggerFacade sLogger = new CommonsLoggingLogger(logger); static final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null); private HashMap> txFeaturesContext = new HashMap>(); private TreeMap featureTypes = new TreeMap(); private String featureBaseName = null; private boolean dropTableMode = true; private int accumulate = 0; public GeneralDgnConvertEdbGeoJobContext(String dataPath, DataStore targetDataStore, String targetSchema, boolean profileMode, boolean useTransform) { super(dataPath, targetDataStore, targetSchema, profileMode, useTransform); } public void putFeatureCollection(Element element) throws IllegalAttributeException, SchemaException { SimpleFeatureType ft = lookupFeatureType(element); if (ft != null) { boolean canLog = true; SimpleFeature feature = null; try { feature = createFeature(ft, element); } catch (ArrayIndexOutOfBoundsException e) { getLogger().warn(e.getMessage(), e); canLog = false; } catch (ClassCastException e) { getLogger().warn(e.getMessage(), e); } if (feature == null) { if (!canLog) return; if (element instanceof TextElement) logger.info("cannot craete feature." + element.toString() + "'" + ((TextElement) element).getText() + "'"); else if (element instanceof ShapeElement) logger.info("cannot craete feature." + element.toString() + "'" + ((ShapeElement) element).getVerticeSize() + "'" + ((ShapeElement) element).getStartPoint()); else if (element instanceof LineStringElement) logger.info("cannot craete feature." + element.toString() + "'" + ((LineStringElement) element).getVerticeSize() + "'" + ((LineStringElement) element).getStartPoint()); else if (element instanceof ArcElement) logger.info("cannot craete feature." + element.toString() + "'" + ((ArcElement) element).getOrigin().toString() + "'" + ((ArcElement) element).getRotationAngle()); return; } if (!txFeaturesContext.containsKey(feature.getFeatureType())) { txFeaturesContext.put(feature.getFeatureType(), new ArrayList()); } ArrayList arrayList = txFeaturesContext.get(feature.getFeatureType()); if (feature.getDefaultGeometry() != null && !((Geometry)feature.getDefaultGeometry()).isEmpty()) { arrayList.add(feature); accumulate++; } } else { logger.info("Unknown Element :" + element.getType() + ", lv=" + element.getLevelIndex()); } if (accumulate > BATCHSIZE) { commitTransaction(); } } // private Transaction transaction; public void startTransaction() { } public void commitTransaction() { if (!txFeaturesContext.isEmpty()) { logger.debug("Transaction size = " + txFeaturesContext.size()); //txFeaturesContext.commitTransaction(); } else { logger.debug("Transaction is empty."); } if (!txFeaturesContext.isEmpty()) { updateDataStore(); } } public void rollbackTransaction() { } private void updateDataStore() { if (isProfileMode()) markUpdateTime(); Iterator it = txFeaturesContext.keySet().iterator(); Connection conn = null; try { conn = getConnection(); boolean autoCommit = conn.getAutoCommit(); conn.setAutoCommit(false); while (it.hasNext()) { SimpleFeatureType featureType = it.next(); logger.debug("Begin Save into EdbGeo:" + featureType.getTypeName()); String bindingStmt = makePrepareInsertSql(featureType); ArrayList features = txFeaturesContext.get(featureType); PreparedStatement pstmt = conn.prepareStatement(bindingStmt); for (SimpleFeature feature : features) { // currentStmt = feature; // Statement stmt = conn.createStatement(); try { // stmt.execute(feature); bindFeatureParameters(pstmt, feature); // pstmt.execute(); pstmt.addBatch(); } catch (PSQLException e) { if (bindingStmt != null) { logger.error("Execute:" + bindingStmt); } logger.error(e.getServerErrorMessage()); logger.error(e.getMessage(), e); } } int[] numUpdates = pstmt.executeBatch(); for (int i = 0; i < numUpdates.length; i++) { if (numUpdates[i] == -2) logger.warn("Execution " + i + ": unknown number of rows updated"); } conn.commit(); JDBCUtils.close(pstmt); features.clear(); logger.debug("End Save into EdbGeo:" + featureType.getTypeName()); } conn.setAutoCommit(autoCommit); JDBCUtils.close(conn, Transaction.AUTO_COMMIT, null); accumulate = 0; } catch (SQLException e) { JDBCUtils.close(conn, Transaction.AUTO_COMMIT, e); logger.error(e.getMessage(), e); } finally { if (isProfileMode()) accumulateUpdateTime(); } } public void closeFeatureWriter() { txFeaturesContext.clear(); /* for (FeatureWriter featureWriter : this.featuresWriterContext.values()) { featureWriter.close(); } this.featuresWriterContext.clear(); */ } public SimpleFeatureType createPointFeatureElement(String featureName) throws SchemaException { if (!featureTypes.containsKey(featureName)) { SimpleFeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalPointFeatureTypeBuilder(featureName); SimpleFeatureType featureType = typeBuilder.buildFeatureType(); featureTypes.put(featureName, featureType); clearFeatureData(typeBuilder); } return featureTypes.get(featureName); } public SimpleFeatureType createPolygonFeatureElement(String featureName) throws SchemaException { if (!featureTypes.containsKey(featureName)) { SimpleFeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalPolygonFeatureTypeBuilder(featureName); SimpleFeatureType featureType = typeBuilder.buildFeatureType(); featureTypes.put(featureName, featureType); clearFeatureData(typeBuilder); } return featureTypes.get(featureName); } public SimpleFeatureType createLineFeatureElement(String featureName) throws SchemaException { if (!featureTypes.containsKey(featureName)) { SimpleFeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalLineFeatureTypeBuilder(featureName); SimpleFeatureType featureType = typeBuilder.buildFeatureType(); featureTypes.put(featureName, featureType); clearFeatureData(typeBuilder); } return featureTypes.get(featureName); } public SimpleFeatureType createMultiLineFeatureElement(String featureName) throws SchemaException { if (!featureTypes.containsKey(featureName)) { SimpleFeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalMultiLineFeatureTypeBuilder(featureName); SimpleFeatureType featureType = typeBuilder.buildFeatureType(); featureTypes.put(featureName, featureType); clearFeatureData(typeBuilder); } return featureTypes.get(featureName); } public SimpleFeatureType createArcFeatureElement(String featureName) throws SchemaException { if (!featureTypes.containsKey(featureName)) { SimpleFeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalArcFeatureTypeBuilder(featureName); SimpleFeatureType featureType = typeBuilder.buildFeatureType(); featureTypes.put(featureName, featureType); clearFeatureData(typeBuilder); } return featureTypes.get(featureName); } public SimpleFeatureType createEllipseFeatureElement(String featureName) throws SchemaException { if (!featureTypes.containsKey(featureName)) { SimpleFeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalEllipseFeatureTypeBuilder(featureName); SimpleFeatureType featureType = typeBuilder.buildFeatureType(); featureTypes.put(featureName, featureType); clearFeatureData(typeBuilder); } return featureTypes.get(featureName); } public SimpleFeature createFeature(SimpleFeatureType featureType, Element element) throws IllegalAttributeException { DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance(); GeometryConverterDecorator convertDecorator = FeatureTypeBuilderUtil.lookupDefaultGeometryConverter(); if (element instanceof TextElement) { TextElement textElement = (TextElement) element; convertDecorator.setConverter(textElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); double angle = textElement.getRotationAngle(); String content = textElement.getText(); content = content.replace('\u0000', ' '); content = content.trim(); angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue(); if (geom != null) { return SimpleFeatureBuilder.build(featureType, new Object[]{ geom, colorTable.getColorCode(textElement.getColorIndex()), textElement.getFontIndex(), textElement.getJustification(), textElement.getTextHeight(), textElement.getTextWidth(), angle, content }, null); } else { logger.info("geometry is null." + element.toString()); } return null; } else if (element instanceof TextNodeElement) { TextNodeElement textNodeElement = (TextNodeElement) element; convertDecorator.setConverter(textNodeElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); double angle = textNodeElement.getRotationAngle(); angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue(); String[] texts = textNodeElement.getTextArray(); StringBuilder sb = new StringBuilder(); for (String text : texts) { if (sb.length() != 0) sb.append("\n"); String content = text.replace('\u0000', ' '); sb.append(content); } if (geom != null) { return SimpleFeatureBuilder.build(featureType, new Object[]{ geom, colorTable.getColorCode(textNodeElement.getColorIndex()), textNodeElement.getFontIndex(), textNodeElement.getJustification(), textNodeElement.getTextNodeHeight(), textNodeElement.getTextNodeLength(), angle, sb.toString() }, null); } else { logger.info("geometry is null." + element.toString()); } return null; } else if (element instanceof ShapeElement) { ShapeElement shapeElement = (ShapeElement) element; convertDecorator.setConverter(shapeElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) { return SimpleFeatureBuilder.build(featureType, new Object[]{ geom, colorTable.getColorCode(shapeElement.getColorIndex()), shapeElement.getWeight(), shapeElement.getLineStyle() }, null); } else { logger.info("geometry is null." + element.toString()); } return null; } else if (element instanceof LineStringElement) { LineStringElement linestring = (LineStringElement) element; convertDecorator.setConverter(linestring); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) { return SimpleFeatureBuilder.build(featureType, new Object[]{ geom, colorTable.getColorCode(linestring.getColorIndex()), linestring.getWeight(), linestring.getLineStyle() }, null); } return null; } else if (element instanceof LineElement) { LineElement line = (LineElement) element; convertDecorator.setConverter(line); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) { return SimpleFeatureBuilder.build(featureType, new Object[]{ geom, colorTable.getColorCode(line.getColorIndex()), line.getWeight(), line.getLineStyle() }, null); } return null; } else if (element instanceof ArcElement) { ArcElement arcElement = (ArcElement) element; /* logger.fatal("" + arcElement.getPrimary() + ":" + arcElement.getSecondary() + "-" + arcElement.getStartAngle() + ":" + arcElement.getSweepAngle() + ":" + arcElement.getRotationAngle() + ":" + arcElement.getOrigin()); */ convertDecorator.setConverter(arcElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) { return SimpleFeatureBuilder.build(featureType, new Object[]{ geom, colorTable.getColorCode(arcElement.getColorIndex()), arcElement.getWeight(), arcElement.getLineStyle() }, null); } return null; } else if (element instanceof EllipseElement) { EllipseElement arcElement = (EllipseElement) element; convertDecorator.setConverter(arcElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) { return SimpleFeatureBuilder.build(featureType, new Object[]{ geom, colorTable.getColorCode(arcElement.getColorIndex()), arcElement.getWeight(), arcElement.getLineStyle() }, null); } return null; } else if (element instanceof ComplexChainElement) { ComplexChainElement complexChainElement = (ComplexChainElement) element; convertDecorator.setConverter(complexChainElement); Geometry geom = convertDecorator.toGeometry(geometryFactory); if (geom != null) { return SimpleFeatureBuilder.build(featureType, new Object[]{ geom, colorTable.getColorCode(complexChainElement.getColorIndex()), complexChainElement.getWeight(), complexChainElement.getLineStyle() }, null); } return null; } return null; } private String getFeatureBaseName() { if (featureBaseName == null) { String dgnname = getFilename().toLowerCase(); int i = dgnname.lastIndexOf("."); if (i != -1) { dgnname = dgnname.substring(0, i); } featureBaseName = dgnname; } return featureBaseName; } private SimpleFeatureType lookupFeatureType(Element element) throws SchemaException, IllegalAttributeException { String typeName; if (element instanceof TextElement) { typeName = getFeatureBaseName() + "_P"; typeName = typeName.toLowerCase(); if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createPointFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof TextNodeElement) { typeName = getFeatureBaseName() + "_P"; typeName = typeName.toLowerCase(); if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createPointFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof LineStringElement) { if (element instanceof ShapeElement) { typeName = getFeatureBaseName() + "_R"; typeName = typeName.toLowerCase(); if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createPolygonFeatureElement(typeName)); } return featureTypes.get(typeName); } else { typeName = getFeatureBaseName() + "_L"; typeName = typeName.toLowerCase(); if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createLineFeatureElement(typeName)); } return featureTypes.get(typeName); } } else if (element instanceof LineElement) { typeName = getFeatureBaseName() + "_L"; typeName = typeName.toLowerCase(); if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createLineFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof ComplexChainElement) { typeName = getFeatureBaseName() + "_ML"; typeName = typeName.toLowerCase(); if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createMultiLineFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof ArcElement) { typeName = getFeatureBaseName() + "_A"; typeName = typeName.toLowerCase(); if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createArcFeatureElement(typeName)); } return featureTypes.get(typeName); } else if (element instanceof EllipseElement) { typeName = getFeatureBaseName() + "_R"; typeName = typeName.toLowerCase(); if (!featureTypes.containsKey(typeName)) { featureTypes.put(typeName, createEllipseFeatureElement(typeName)); } return featureTypes.get(typeName); } return null; } protected FrammeAttributeData getFeatureLinkage(Element element) { if (!element.hasUserAttributeData()) return null; List usrDatas = element.getUserAttributeData(); for (UserAttributeData anUsrData : usrDatas) { if (anUsrData instanceof FrammeAttributeData) { return (FrammeAttributeData) anUsrData; } } return null; } public Log getLogger() { return logger; } public boolean isDropTableMode() { return dropTableMode; } public void setDropTableMode(boolean dropTableMode) { this.dropTableMode = dropTableMode; } protected void clearFeatureData(SimpleFeatureTypeBuilder typeBuilder) throws SchemaException { if (isProfileMode()) markUpdateTime(); String featureName = typeBuilder.getName(); Connection conn = null; if (isExistFeature(typeBuilder.buildFeatureType())) { try { conn = getConnection(); if (dropTableMode) { dropGeometryColumn(conn, featureName, ((FeatureTypeImpl)typeBuilder.buildFeatureType()).getGeometryDescriptor().getLocalName()); dropTable(conn, featureName); ArrayList schemaTexts = createNewSchemaTexts(conn, typeBuilder.buildFeatureType()); for (String stmtText : schemaTexts) { Statement stmt = conn.createStatement(); stmt.execute(stmtText); JDBCUtils.close(stmt); } } else { deleteTable(conn, featureName); } JDBCUtils.close(conn, Transaction.AUTO_COMMIT, null); } catch (IOException e) { JDBCUtils.close(conn, Transaction.AUTO_COMMIT, null); logger.warn(e.getMessage(), e); } catch (SQLException e) { JDBCUtils.close(conn, Transaction.AUTO_COMMIT, e); logger.warn(e.getMessage(), e); } finally { if (isProfileMode()) accumulateUpdateTime(); } } else { try { conn = getConnection(); ArrayList schemaTexts = createNewSchemaTexts(conn, typeBuilder.buildFeatureType()); for (String stmtText : schemaTexts) { Statement stmt = conn.createStatement(); stmt.execute(stmtText); JDBCUtils.close(stmt); } JDBCUtils.close(conn, Transaction.AUTO_COMMIT, null); } catch (IOException e) { JDBCUtils.close(conn, Transaction.AUTO_COMMIT, null); logger.warn(e.getMessage(), e); } catch (SQLException e) { JDBCUtils.close(conn, Transaction.AUTO_COMMIT, e); logger.warn(e.getMessage(), e); } finally { if (isProfileMode()) accumulateUpdateTime(); } } } }