forked from geodmms/xdgnjobs

?? ?
2008-05-28 92fe8e29a4df7ad12b2f13661f1c326b6b78644a
tag 0.3a
1 files modified
93 files added
30766 ■■■■■ changed files
.gitattributes 93 ●●●●● patch | view | raw | blame | history
xdgnjobs/pom.xml 750 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/pom.xml 70 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ArcElement.java 231 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java 247 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexElement.java 16 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexShapeElement.java 217 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7Exception.java 24 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7OracleReader.java 243 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileException.java 24 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileHeader.java 58 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java 722 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java 274 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java 385 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/EllipseElement.java 211 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/FrammeAttributeData.java 71 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/GeometryConverter.java 18 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/IElementHandler.java 23 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineElement.java 130 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineStringElement.java 171 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Lock.java 263 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/NIOUtilities.java 114 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ShapeElement.java 62 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/StreamLogging.java 45 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TcbElement.java 94 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java 340 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java 289 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/UserAttributeData.java 34 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/util/DgnUtility.java 259 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/util/PrintfFormat.java 4774 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7OracleReaderTest.java 125 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7TextElementReaderTest.java 180 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileReaderTest.java 119 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/OracleTarget.java 162 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/Demo.dgn patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88491-1.dgn patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88491_0888888.dgn patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88494_0.dgn patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/testHV.dgn patch | view | raw | blame | history
xdgnjobs/ximple-jobcarrier/pom.xml 141 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-jobcarrier/src/main/java/com/ximple/eofms/XQuartzJobCarrier.java 95 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-jobcarrier/src/main/resources/log4j.properties 28 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-jobcarrier/src/main/resources/quartz.properties 28 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-jobcarrier/src/main/resources/quartz_jobs.xml 99 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-jobcarrier/src/test/java/com/ximple/eofms/XQuartzJobCarrierTest.java 19 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/pom.xml 73 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/AbstractDispatchableFilter.java 75 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/AbstractFLinkageDispatchableFilter.java 26 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateArcLineStringStrategy.java 96 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateEllipseShapeStrategy.java 97 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateFeatureTypeStrategy.java 15 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineStringStrategy.java 147 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineTextStrategy.java 164 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateShapeStrategy.java 112 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateSymbolStrategy.java 126 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateTextStrategy.java 142 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementDispatchableFilter.java 12 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementDispatcher.java 39 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementLevelCriterion.java 48 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementTypeCriterion.java 48 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/TypeCompIdDispatchableFilter.java 101 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/TypeCompLevelIdDispatchableFilter.java 108 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/TypeIdDispatchableFilter.java 82 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/AbstractDgnFileJobContext.java 82 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/AbstractOracleDatabaseJob.java 305 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/AbstractOracleJobContext.java 326 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/DummyFeatureConvertJobContext.java 297 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/FeatureDgnConvertJobContext.java 280 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/GeneralDgnConvertJobContext.java 554 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/IndexDgnConvertJobContext.java 355 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertDgn2ShpJob.java 917 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertJobContext.java 347 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleElementLogger.java 314 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleUpgradeBlob2UDTJob.java 60 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleUpgradeJobContext.java 16 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/TWD97GeometryConverterDecorator.java 69 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/Base64.java 551 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/BinConverter.java 363 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/Bits.java 323 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/ByteArrayCompressor.java 97 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/ColorTableMapping.java 12 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/DefaultColorTable.java 363 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/GeomUtil.java 30 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/LangUtil.java 104 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/PrintfFormat.java 4774 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/StringUtils.java 2923 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TPCLIDConverter.java 758 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWDDatumConverter.java 508 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/ElementDispatcherRules.xml 161 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/resources/conf/ConvertShpFilterForLayer.xml 17 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/resources/conf/DefaultConvertShpFilter.xml 1465 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/test/java/com/ximple/eofms/filter/ElementDispatcherTest.java 69 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testElementFilter.xml 1406 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testRules.xml 161 ●●●●● patch | view | raw | blame | history
.gitattributes
@@ -1 +1,94 @@
* text=auto !eol
xdgnjobs/pom.xml svneol=native#text/xml
xdgnjobs/ximple-dgnio/pom.xml svneol=native#text/xml
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ArcElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexShapeElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7Exception.java -text
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7OracleReader.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileException.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileHeader.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/EllipseElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/FrammeAttributeData.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/GeometryConverter.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/IElementHandler.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineStringElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Lock.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/NIOUtilities.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ShapeElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/StreamLogging.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TcbElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/UserAttributeData.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/util/DgnUtility.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/util/PrintfFormat.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7OracleReaderTest.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7TextElementReaderTest.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileReaderTest.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/OracleTarget.java svneol=native#text/plain
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/Demo.dgn -text
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88491-1.dgn -text
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88491_0888888.dgn -text
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88494_0.dgn -text
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/testHV.dgn -text
xdgnjobs/ximple-jobcarrier/pom.xml svneol=native#text/xml
xdgnjobs/ximple-jobcarrier/src/main/java/com/ximple/eofms/XQuartzJobCarrier.java svneol=native#text/plain
xdgnjobs/ximple-jobcarrier/src/main/resources/log4j.properties svneol=native#text/plain
xdgnjobs/ximple-jobcarrier/src/main/resources/quartz.properties svneol=native#text/plain
xdgnjobs/ximple-jobcarrier/src/main/resources/quartz_jobs.xml svneol=native#text/xml
xdgnjobs/ximple-jobcarrier/src/test/java/com/ximple/eofms/XQuartzJobCarrierTest.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/pom.xml svneol=native#text/xml
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/AbstractDispatchableFilter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/AbstractFLinkageDispatchableFilter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateArcLineStringStrategy.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateEllipseShapeStrategy.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateFeatureTypeStrategy.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineStringStrategy.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineTextStrategy.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateShapeStrategy.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateSymbolStrategy.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateTextStrategy.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementDispatchableFilter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementDispatcher.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementLevelCriterion.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementTypeCriterion.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/TypeCompIdDispatchableFilter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/TypeCompLevelIdDispatchableFilter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/TypeIdDispatchableFilter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/AbstractDgnFileJobContext.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/AbstractOracleDatabaseJob.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/AbstractOracleJobContext.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/DummyFeatureConvertJobContext.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/FeatureDgnConvertJobContext.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/GeneralDgnConvertJobContext.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/IndexDgnConvertJobContext.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertDgn2ShpJob.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertJobContext.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleElementLogger.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleUpgradeBlob2UDTJob.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleUpgradeJobContext.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/TWD97GeometryConverterDecorator.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/Base64.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/BinConverter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/Bits.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/ByteArrayCompressor.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/ColorTableMapping.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/DefaultColorTable.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/GeomUtil.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/LangUtil.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/PrintfFormat.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/StringUtils.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TPCLIDConverter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWDDatumConverter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/ElementDispatcherRules.xml svneol=native#text/xml
xdgnjobs/ximple-spatialjob/src/main/resources/conf/ConvertShpFilterForLayer.xml svneol=native#text/xml
xdgnjobs/ximple-spatialjob/src/main/resources/conf/DefaultConvertShpFilter.xml svneol=native#text/xml
xdgnjobs/ximple-spatialjob/src/test/java/com/ximple/eofms/filter/ElementDispatcherTest.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testElementFilter.xml svneol=native#text/xml
xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testRules.xml svneol=native#text/xml
xdgnjobs/pom.xml
New file
@@ -0,0 +1,750 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- =======================================================================
  Maven Project Configuration File
  The Ximple DgnIO Project
  http://www.ximple.com.tw/
  Version: $Id$
  ======================================================================= -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <properties>
    <oracle.jdbc>true</oracle.jdbc>
    <test.maxHeapSize>512M</test.maxHeapSize>
    <src.output>${basedir}/target</src.output>
    <java5>1.5</java5>
    <xdgnio.version>0.3.0</xdgnio.version>
    <gt.version>2.4.2</gt.version>
    <failIfNoTests>false</failIfNoTests>
  </properties>
  <profiles>
    <profile>
      <id>java5</id>
      <reporting>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <configuration>
              <source>1.5</source>
            </configuration>
          </plugin>
        </plugins>
      </reporting>
    </profile>
    <profile>
      <id>site.ximple.tw</id>
      <distributionManagement>
        <site>
          <id>artifactorysite-ximple-tw</id>
          <name>Artifactory Web site for Maven reports</name>
          <url>scp://www.ximple.com.tw/home/www/artfactory/libs-releases@repo</url>
        </site>
      </distributionManagement>
    </profile>
  </profiles>
  <scm>
    <connection>
      scm:svn:http://www.ximple.com.tw/svn/xeofms/xspatialjob/truck/
    </connection>
    <url>http://www.ximple.com.tw/svn/xeofms/xspatialjob/truck/</url>
  </scm>
  <groupId>com.ximple.eofms</groupId>
  <artifactId>ximple-dgnjobs</artifactId>
  <packaging>pom</packaging>
  <version>0.3.0</version>
  <name>ximple-dgnjobs</name>
  <url>http://www.ximple.com.tw</url>
  <description>Ximple Spatial Data Job for Quartz</description>
  <organization>
    <name>Ximple</name>
    <url>http://www.ximple.com.tw</url>
  </organization>
  <inceptionYear>2008</inceptionYear>
  <!-- =========================================================== -->
  <!--     Issue managements and mailing lists.                    -->
  <!-- =========================================================== -->
  <issueManagement>
    <system>JIRA</system>
    <url>http://www.ximple.com.tw/jira/browse/EOFMS</url>
  </issueManagement>
  <!-- =========================================================== -->
  <!--    Continuous Integration                                   -->
  <!-- =========================================================== -->
  <ciManagement>
    <system>continuum</system>
  </ciManagement>
  <mailingLists>
    <mailingList>
    </mailingList>
  </mailingLists>
  <developers>
    <developer>
    </developer>
  </developers>
  <contributors>
  </contributors>
  <!-- =========================================================== -->
  <!--     Dependency Management                                   -->
  <!--     If a POM declares one of those dependencies, then it    -->
  <!--     will use the version specified here. Otherwise, those   -->
  <!--     dependencies are ignored.                               -->
  <!-- =========================================================== -->
  <dependencyManagement>
    <dependencies>
      <!-- GeoAPI and its dependencies -->
      <dependency>
        <groupId>org.opengis</groupId>
        <artifactId>geoapi-nogenerics</artifactId>
        <version>2.1.0</version>
      </dependency>
      <dependency>
        <groupId>javax.units</groupId>
        <artifactId>jsr108</artifactId>
        <version>0.01</version>
      </dependency>
      <dependency>
        <groupId>com.vividsolutions</groupId>
        <artifactId>jts</artifactId>
        <version>1.9</version>
      </dependency>
      <!-- Apache -->
      <!--
      <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.7</version>
      </dependency>
      -->
      <dependency>
        <groupId>commons-collections</groupId>
        <artifactId>commons-collections</artifactId>
        <version>3.2.1</version>
      </dependency>
      <dependency>
        <groupId>commons-digester</groupId>
        <artifactId>commons-digester</artifactId>
        <version>1.8</version>
      </dependency>
      <dependency>
        <groupId>commons-pool</groupId>
        <artifactId>commons-pool</artifactId>
        <version>1.4</version>
      </dependency>
      <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
      </dependency>
      <dependency>
        <groupId>commons-transaction</groupId>
        <artifactId>commons-transaction</artifactId>
        <version>1.2</version>
      </dependency>
      <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.15</version>
        <!-- Same as the dependency in commons-logging -->
      </dependency>
      <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-contrib</artifactId>
        <version>3.0.2-FINAL</version>
      </dependency>
      <!-- geotools -->
      <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt2</artifactId>
        <version>${gt.version}</version>
      </dependency>
      <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt2-api</artifactId>
        <version>${gt.version}</version>
      </dependency>
      <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt2-main</artifactId>
        <version>${gt.version}</version>
      </dependency>
      <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt2-shapefile</artifactId>
        <version>${gt.version}</version>
      </dependency>
      <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt2-sample-data</artifactId>
        <version>${gt.version}</version>
        <scope>test</scope>
      </dependency>
      <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt2-data</artifactId>
        <version>${gt.version}</version>
      </dependency>
      <!-- because main and sample-data depend on referencing we need a tie breaker -->
      <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt2-referencing</artifactId>
        <version>${gt.version}</version>
      </dependency>
      <dependency>
        <groupId>jdom</groupId>
        <artifactId>jdom</artifactId>
        <version>1.0</version>
      </dependency>
      <dependency>
        <groupId>velocity</groupId>
        <artifactId>velocity</artifactId>
        <version>1.4</version>
      </dependency>
      <!-- We need this to make the referencing module useful -->
      <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt2-epsg-hsql</artifactId>
        <version>${gt.version}</version>
        <scope>test</scope>
      </dependency>
      <!-- ORACLE -->
      <!-- Download and install into your own repo -->
      <dependency>
        <artifactId>ojdbc5</artifactId>
        <groupId>com.oracle</groupId>
        <version>11.1.0</version>
      </dependency>
      <!-- opensymphony -->
      <dependency>
        <groupId>opensymphony</groupId>
        <artifactId>quartz</artifactId>
        <version>1.6.0</version>
      </dependency>
      <!-- Ximple Library -->
      <dependency>
        <artifactId>ximple-dgnio</artifactId>
        <groupId>com.ximple</groupId>
        <version>${xdgnio.version}</version>
      </dependency>
      <!-- Tests or legacy -->
      <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>5.7</version>
        <scope>test</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <!-- =========================================================== -->
  <!--     Dependencies to be inherited by all modules.            -->
  <!-- =========================================================== -->
  <dependencies>
    <dependency>
      <artifactId>geoapi-nogenerics</artifactId>
      <groupId>org.opengis</groupId>
    </dependency>
    <dependency>
      <artifactId>jsr108</artifactId>
      <groupId>javax.units</groupId>
    </dependency>
    <dependency>
      <groupId>com.vividsolutions</groupId>
      <artifactId>jts</artifactId>
    </dependency>
    <!-- Apache -->
    <dependency>
      <artifactId>commons-collections</artifactId>
      <groupId>commons-collections</groupId>
    </dependency>
    <dependency>
      <groupId>commons-digester</groupId>
      <artifactId>commons-digester</artifactId>
    </dependency>
    <dependency>
      <groupId>commons-pool</groupId>
      <artifactId>commons-pool</artifactId>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
    </dependency>
    <dependency>
      <groupId>commons-transaction</groupId>
      <artifactId>commons-transaction</artifactId>
    </dependency>
    <dependency>
      <artifactId>log4j</artifactId>
      <groupId>log4j</groupId>
    </dependency>
    <dependency>
      <artifactId>gt2-api</artifactId>
      <groupId>org.geotools</groupId>
    </dependency>
    <dependency>
      <artifactId>gt2-main</artifactId>
      <groupId>org.geotools</groupId>
    </dependency>
    <dependency>
      <artifactId>gt2-shapefile</artifactId>
      <groupId>org.geotools</groupId>
    </dependency>
    <dependency>
      <artifactId>gt2-sample-data</artifactId>
      <groupId>org.geotools</groupId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <artifactId>gt2-data</artifactId>
      <groupId>org.geotools</groupId>
    </dependency>
    <!-- because main and sample-data depend on referencing we need a tie breaker -->
    <dependency>
      <artifactId>gt2-referencing</artifactId>
      <groupId>org.geotools</groupId>
    </dependency>
    <dependency>
      <artifactId>jdom</artifactId>
      <groupId>jdom</groupId>
    </dependency>
    <dependency>
      <artifactId>velocity</artifactId>
      <groupId>velocity</groupId>
    </dependency>
    <!-- We need this to make the referencing module useful -->
    <dependency>
      <artifactId>gt2-epsg-hsql</artifactId>
      <groupId>org.geotools</groupId>
      <scope>test</scope>
    </dependency>
    <!-- ORACLE -->
    <dependency>
      <artifactId>ojdbc5</artifactId>
      <groupId>com.oracle</groupId>
    </dependency>
    <dependency>
      <artifactId>testng</artifactId>
      <groupId>org.testng</groupId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <!-- =========================================================== -->
  <!--     Build Configuration                                     -->
  <!-- =========================================================== -->
  <build>
    <!-- ========================================================= -->
    <!--   Maven plugins dependencies management.                  -->
    <!--   It should not be needed since Maven select by default   -->
    <!--   the latest plugins. Unfortunatly, experience shows that -->
    <!--   new plugin releases sometime introduce new bugs that    -->
    <!--   break our build. So it is saferto specify plugin        -->
    <!--   versions that are known to work.  This list is in       -->
    <!--   alphabetical order for easier comparaison with latest   -->
    <!--   plugins at                                              -->
    <!--   http://www.ibiblio.org/maven2/org/apache/maven/plugins/ -->
    <!-- ========================================================= -->
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.1</version>
          <configuration>
            <descriptors>
              <descriptor>build/maven/assembly/binaryDist.xml</descriptor>
              <descriptor>build/maven/assembly/sourceDist.xml</descriptor>
            </descriptors>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-clean-plugin</artifactId>
          <version>2.1.1</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-clover-plugin</artifactId>
          <version>2.3</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>2.0.2</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.1</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <version>2.1</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-javadoc-plugin</artifactId>
          <version>2.2</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-plugin-plugin</artifactId>
          <version>2.3</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-pmd-plugin</artifactId>
          <version>2.2</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>2.0.1</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-resources-plugin</artifactId>
          <version>2.2</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-site-plugin</artifactId>
          <version>2.0-beta-5</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.4.2</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-report-plugin</artifactId>
          <version>2.3</version>
        </plugin>
        <!-- http://www.ibiblio.org/maven2/org/codehaus/mojo/ -->
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>changelog-maven-plugin</artifactId>
          <version>2.0-beta-1</version>
        </plugin>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>changes-maven-plugin</artifactId>
          <version>2.0-beta-1</version>
        </plugin>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>jxr-maven-plugin</artifactId>
          <version>2.0-beta-1</version>
        </plugin>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>taglist-maven-plugin</artifactId>
          <version>2.0</version>
        </plugin>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>jalopy-maven-plugin</artifactId>
          <version>1.0-SNAPSHOT</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-source-plugin</artifactId>
          <configuration>
            <outputDirectory>${src.output}</outputDirectory>
            <attach>false</attach>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-eclipse-plugin</artifactId>
          <version>2.4</version>
        </plugin>
      </plugins>
    </pluginManagement>
    <!-- http://www.ibiblio.org/maven2/org/apache/maven/wagon/ -->
    <extensions>
      <extension>
        <groupId>org.apache.maven.wagon</groupId>
        <artifactId>wagon-webdav</artifactId>
        <version>1.0-beta-2</version>
      </extension>
    </extensions>
    <plugins>
      <!-- ======================================================= -->
      <!--     Source reformat                                     -->
      <!--       (activated only on request, jalopy:format)        -->
      <!--     See developer's guide for automated activation      -->
      <!-- ======================================================= -->
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>jalopy-maven-plugin</artifactId>
        <configuration>
          <convention>gt2/jalopygeotools.xml</convention>
          <failOnError>false</failOnError>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.geotools.maven</groupId>
            <artifactId>gt2-build-configs</artifactId>
            <version>${project.version}</version>
          </dependency>
        </dependencies>
      </plugin>
      <!-- ======================================================= -->
      <!--     Compilation.                                        -->
      <!-- ======================================================= -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <!-- The -source argument for the Java compiler. -->
          <target>1.5</target>
          <!-- The -target argument for the Java compiler. -->
          <debug>true</debug>
          <!-- Whether to include debugging information.   -->
          <encoding>ISO-8859-1</encoding>
          <!-- The -encoding argument for the Java compiler. -->
        </configuration>
      </plugin>
      <!-- ======================================================= -->
      <!--     Tests.                                              -->
      <!-- ======================================================= -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <includes>
            <include>**/*Test.java</include>
          </includes>
          <excludes>
            <exclude>${online.skip.pattern}</exclude>
            <exclude>${stress.skip.pattern}</exclude>
          </excludes>
          <argLine>-Xmx${test.maxHeapSize} -Djava.awt.headless=${java.awt.headless}
          </argLine>
          <!-- Ignores test failure only if we are generating a       -->
          <!-- report for publication on the web site. See the        -->
          <!-- profiles section at the begining of this pom.xml file. -->
          <testFailureIgnore>
            ${allow.test.failure.ignore}
          </testFailureIgnore>
          <!-- Option to print summary of test suites or just print the test cases that has errors. -->
          <printSummary>true</printSummary>
          <!-- Redirect the unit test standard output to a file. -->
          <redirectTestOutputToFile>false</redirectTestOutputToFile>
        </configuration>
      </plugin>
      <!-- ======================================================= -->
      <!--     Code coverage                                       -->
      <!-- ======================================================= -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-clover-plugin</artifactId>
        <configuration>
          <jdk>1.5</jdk>
          <licenseLocation>
            http://svn.geotools.org/geotools/branches/2.4.x/build/maven/build-configs/src/main/resources/gt2/clover.license
          </licenseLocation>
          <flushPolicy>directed</flushPolicy>
        </configuration>
        <executions>
          <execution>
            <phase>pre-site</phase>
            <goals>
              <goal>instrument</goal>
              <!-- aggregation is disabled due to the bug:     -->
              <!-- http://jira.codehaus.org/browse/MCLOVER-34  -->
            </goals>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.geotools.maven</groupId>
            <artifactId>gt2-build-configs</artifactId>
            <version>${project.version}</version>
          </dependency>
        </dependencies>
      </plugin>
      <!-- ======================================================= -->
      <!--     JAR packaging.                                      -->
      <!-- ======================================================= -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <!-- ======================================================= -->
      <!--     Source packaging.                                      -->
      <!-- ======================================================= -->
      <plugin>
        <inherited>true</inherited>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <configuration>
          <attach>true</attach>
        </configuration>
        <executions>
          <execution>
            <id>attach-sources</id>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
    <resources>
      <!--
      <resource>
        <targetPath>conf</targetPath>
        <filtering>false</filtering>
        <directory>${basedir}/src/main/resources/conf</directory>
        <includes>
          <include>configuration.xml</include>
        </includes>
        <excludes>
          <exclude>**/*.properties</exclude>
        </excludes>
      </resource>
        -->
    </resources>
  </build>
  <distributionManagement>
    <repository>
      <uniqueVersion>false</uniqueVersion>
      <id>ximple</id>
      <name>Ximple - Artifactory lib repo</name>
      <url>dav:http://www.ximple.com.tw/artifactory/libs-releases</url>
    </repository>
    <snapshotRepository>
      <uniqueVersion>false</uniqueVersion>
      <id>ximple-snapshots</id>
      <name>Ximple - Artifactory lib-snapshots repo</name>
      <url>dav:http://www.ximple.com.tw/artifactory/libs-snapshots</url>
    </snapshotRepository>
  </distributionManagement>
  <!-- =========================================================== -->
  <!--     Repositories (ibiblio, refractions...).                 -->
  <!--     This is where Maven looks for dependencies.             -->
  <!-- =========================================================== -->
  <repositories>
    <repository>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <id>central</id>
      <name>Ximple Artifactory Maven Repository Switchboard</name>
      <url>http://www.ximple.com.tw/artifactory/repo</url>
    </repository>
    <repository>
      <releases>
        <enabled>false</enabled>
      </releases>
      <id>snapshots</id>
      <name>Ximple Artifactory Maven Repository Switchboard</name>
      <url>http://www.ximple.com.tw/artifactory/repo</url>
    </repository>
  </repositories>
  <!-- =========================================================== -->
  <!--     Plugin repositories.                                    -->
  <!--     This is where Maven looks for plugin dependencies.      -->
  <!-- =========================================================== -->
  <pluginRepositories>
    <pluginRepository>
      <id>ximple-snapshots</id>
      <name>ximple-shapshots</name>
      <url>http://www.ximple.com.tw/artifactory/vplugins-snapshots</url>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
      <releases>
        <enabled>false</enabled>
      </releases>
    </pluginRepository>
    <pluginRepository>
      <id>ximple</id>
      <name>Ximple Maven 2 Repository</name>
      <url>http://www.ximple.com.tw/artifactory/vplugins-releases</url>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <enabled>true</enabled>
      </releases>
    </pluginRepository>
  </pluginRepositories>
  <!-- =========================================================== -->
  <!--     Modules for the build in approximate dependency order   -->
  <!-- =========================================================== -->
  <modules>
    <module>ximple-dgnio</module>
    <module>ximple-spatialjob</module>
    <module>ximple-jobcarrier</module>
  </modules>
</project>
xdgnjobs/ximple-dgnio/pom.xml
New file
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.ximple.eofms</groupId>
    <artifactId>ximple-dgnjobs</artifactId>
    <version>0.3.0</version>
  </parent>
  <!-- =========================================================== -->
  <!--     Module Description                                      -->
  <!-- =========================================================== -->
  <groupId>com.ximple.eofms</groupId>
  <artifactId>ximple-dgnio</artifactId>
  <version>0.3.0</version>
  <packaging>jar</packaging>
  <name>ximple-dgnio-1.0.x</name>
  <url>http://www.ximple.com.tw</url>
  <scm>
    <connection>
      scm:svn:http://www.ximple.com.tw/svn/xeofms/xdgnio/truck/
    </connection>
    <url>http://www.ximple.com.tw/svn/xeofms/xdgnio/truck/</url>
  </scm>
  <description>
    Ximple Dgn IO Library
  </description>
  <organization>
    <name>Ximple</name>
    <url>http://www.ximple.com.tw</url>
  </organization>
  <inceptionYear>2008</inceptionYear>
  <developers>
    <developer>
      <name>Kuo-Feng Kao</name>
      <id>ulysseskao</id>
      <email>ulysseskao@ximple.com.tw</email>
      <organization>Ximple</organization>
      <roles>
        <role>Java Developer</role>
      </roles>
    </developer>
  </developers>
  <contributors>
  </contributors>
  <!-- =========================================================== -->
  <!--     Dependencies to be inherited by all modules.            -->
  <!-- =========================================================== -->
  <dependencies>
  </dependencies>
  <!-- =========================================================== -->
  <!--     Build Configuration                                     -->
  <!-- =========================================================== -->
  <build>
    <plugins>
    </plugins>
  </build>
</project>
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ArcElement.java
New file
@@ -0,0 +1,231 @@
package com.ximple.io.dgn7;
import java.nio.ByteOrder;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.util.DgnUtility;
/**
 * ArcElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/26 ¤U¤È 06:41:45
 */
public class ArcElement extends Element implements GeometryConverter
{
    private static final Logger logger = Logger.getLogger(ArcElement.class);
    public ArcElement(byte[] raw)
    {
        super(raw);
    }
    public double getStartAngle()
    {
        int angle = (raw[18] & 0x0000ffff) << 16 | (raw[19] & 0x0000ffff);
        return DgnUtility.converIntToRotation(angle);
    }
    public void setStartAngle(double value)
    {
        int angle = DgnUtility.converRotatioToInt(value);
        raw[18] = (short) (angle >>> 16 & 0x0000ffff);
        raw[19] = (short) (angle & 0x0000ffff);
    }
    public double getSweepAngle()
    {
        int angle = (raw[20] & 0x0000ffff) << 16 | (raw[21] & 0x0000ffff);
        if (angle < 0)
            angle = -1 * (angle & 0x7fffffff);
        return DgnUtility.converIntToRotation(angle);
    }
    public void setSweepAngle(double value)
    {
        int angle = DgnUtility.converRotatioToInt(value);
        if (angle < 0)
        {
            angle &= 0x7fffffff;
            angle |= 0x80000000;
        }
        raw[20] = (short) (angle >> 16 & 0x0000ffff);
        raw[21] = (short) (angle & 0x0000ffff);
    }
    public double getPrimary()
    {
        rawBuffer.position(22 * 2);
        ByteOrder bo = rawBuffer.order();
        rawBuffer.order(ByteOrder.BIG_ENDIAN);
        byte[] primary = new byte[8];
        rawBuffer.get(primary);
        rawBuffer.order(bo);
        return DgnUtility.convertDGNToIEEEDouble(primary) / 1000.0;
    }
    public void setPrimary(double value)
    {
        double temp = value * 1000.0;
        short[] primary = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(primary, 0, raw, 22, 4);
    }
    public double getSecondary()
    {
        rawBuffer.position(26 * 2);
        ByteOrder bo = rawBuffer.order();
        rawBuffer.order(ByteOrder.BIG_ENDIAN);
        byte[] secondary = new byte[8];
        rawBuffer.get(secondary);
        rawBuffer.order(bo);
        return DgnUtility.convertDGNToIEEEDouble(secondary) / 1000.0;
    }
    public void setSecondary(double value)
    {
        double temp = value * 1000.0;
        short[] secondary = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(secondary, 0, raw, 26, 4);
    }
    public double getRotationAngle()
    {
        int rotation = (raw[30] << 16 & 0xffff0000);
        rotation |= raw[31] & 0x0000ffff;
        return DgnUtility.converIntToRotation(rotation);
    }
    public void setRotationAngle(double value)
    {
        int angle = DgnUtility.converRotatioToInt(value);
        raw[30] = (short) (angle >> 16 & 0x0000ffff);
        raw[31] = (short) (angle & 0x0000ffff);
    }
    public Coordinate getOrigin()
    {
        rawBuffer.position(32 * 2);
        ByteOrder bo = rawBuffer.order();
        rawBuffer.order(ByteOrder.BIG_ENDIAN);
        byte[] rawValue = new byte[8];
        rawBuffer.get(rawValue); // x
        double dx = DgnUtility.converUnitToCoord(DgnUtility.convertDGNToIEEEDouble(rawValue));
        rawBuffer.get(rawValue); // y
        double dy = DgnUtility.converUnitToCoord(DgnUtility.convertDGNToIEEEDouble(rawValue));
        rawBuffer.order(bo);
        return new Coordinate(dx, dy);
    }
    public void setOrigin(Coordinate value)
    {
        double temp = DgnUtility.converCoordToUnit(value.x);
        short[] x = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(x, 0, raw, 32, 4);
        temp = DgnUtility.converCoordToUnit(value.y);
        short[] y = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(y, 0, raw, 36, 4);
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        double sweep = getSweepAngle();
        double temp = Math.abs(sweep);
        temp /= 4;
        int pts = (temp < 3) ? 3 : (int) temp;
        return factory.createLineString(convertToLineString(pts));
    }
    private Coordinate[] convertToLineString(int pts)
    {
        ArrayList<Coordinate> result = new ArrayList<Coordinate>();
        double beta = DgnUtility.converRotationToRadian(-getRotationAngle());
        double startAngle = getStartAngle();
        double sweepAngle = getSweepAngle();
        double endAngle = startAngle + sweepAngle;
        double steps = sweepAngle / pts;
        double current;
        if (sweepAngle < 0)
        {
            for (current = startAngle; current > endAngle; current += steps)
            {
                Coordinate pt = computePointOnArcByAngle(beta, current);
                result.add(pt);
            }
        } else
        {
            for (current = startAngle; current < endAngle; current += steps)
            {
                Coordinate pt = computePointOnArcByAngle(beta, current);
                result.add(pt);
            }
        }
        Coordinate pt = computePointOnArcByAngle(beta, endAngle);
        result.add(pt);
        return result.toArray(new Coordinate[result.size()]);
    }
    private Coordinate computePointOnArcByAngle(double beta, double current)
    {
        double sinbeta = Math.sin(beta);
        double cosbeta = Math.cos(beta);
        Coordinate pt = new Coordinate();
        double alpha = DgnUtility.converRotationToRadian(current);
        double sinalpha = Math.sin(alpha);
        double cosalpha = Math.cos(alpha);
        pt.x = getOrigin().x + (getPrimary() * cosalpha * cosbeta -
                getSecondary() * sinalpha * sinbeta);
        pt.y = getOrigin().y + (getPrimary() * cosalpha * sinbeta +
                getSecondary() * sinalpha * cosbeta);
        return pt;
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.ARC);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new ArcElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java
New file
@@ -0,0 +1,247 @@
package com.ximple.io.dgn7;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.CoordinateList;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
 * ComplexChainElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 03:44:56
 */
public class ComplexChainElement extends Element implements ComplexElement, GeometryConverter
{
    private static final Logger logger = Logger.getLogger(ComplexChainElement.class);
    protected ArrayList<Element> list = new ArrayList<Element>();
    public ComplexChainElement(byte[] raw)
    {
        super(raw);
        attrOffset = 4;
    }
    public int size()
    {
        return list.size();
    }
    public boolean isEmpty()
    {
        return list.isEmpty();
    }
    public boolean contains(Object o)
    {
        return list.contains(o);
    }
    public Iterator iterator()
    {
        return list.iterator();
    }
    public Object[] toArray()
    {
        return list.toArray();
    }
    public boolean add(Object o)
    {
        return list.add((Element) o);
    }
    public boolean remove(Object o)
    {
        return list.remove(o);
    }
    public boolean addAll(Collection c)
    {
        return list.addAll(c);
    }
    public boolean addAll(int index, Collection c)
    {
        return list.addAll(index, c);
    }
    public void clear()
    {
        list.clear();
    }
    public Object get(int index)
    {
        return list.get(index);
    }
    public Object set(int index, Object element)
    {
        return list.set(index, (Element) element);
    }
    public void add(int index, Object element)
    {
        list.add(index, (Element) element);
    }
    public Object remove(int index)
    {
        return list.remove(index);
    }
    public int indexOf(Object o)
    {
        return list.indexOf(o);
    }
    public int lastIndexOf(Object o)
    {
        return list.lastIndexOf(o);
    }
    public ListIterator listIterator()
    {
        return list.listIterator();
    }
    public ListIterator listIterator(int index)
    {
        return list.listIterator(index);
    }
    public List subList(int fromIndex, int toIndex)
    {
        return list.subList(fromIndex, toIndex);
    }
    public boolean retainAll(Collection c)
    {
        return list.retainAll(c);
    }
    public boolean removeAll(Collection c)
    {
        return list.removeAll(c);
    }
    public boolean containsAll(Collection c)
    {
        return list.containsAll(c);
    }
    public Object[] toArray(Object[] a)
    {
        return list.toArray(a);
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        if (size() == 1)
        {
            Element element = (Element) get(0);
            if (element instanceof LineStringElement)
            {
                if (((LineStringElement) element).getVerticeSize() == 0 || ((LineStringElement) element).getVerticeSize() > 1)
                {
                    return ((LineStringElement) element).toGeometry(factory);
                }
            } else if (element instanceof LineElement)
            {
                if (((LineElement) element).getVertices().length == 0 || ((LineElement) element).getVertices().length > 1)
                {
                    return ((LineElement) element).toGeometry(factory);
                }
            } else
            {
                if (element instanceof GeometryConverter)
                {
                    return ((GeometryConverter) element).toGeometry(factory);
                }
                return null;
            }
        }
        CoordinateList pts = new CoordinateList();
        for (ListIterator it = listIterator(); it.hasNext();)
        {
            Element element = (Element) it.next();
            if (element instanceof LineStringElement)
            {
                if (((LineStringElement) element).getVerticeSize() == 0 || ((LineStringElement) element).getVerticeSize() > 1)
                {
                    pts.add(((LineStringElement) element).toGeometry(factory).getCoordinates(), true);
                }
            } else if (element instanceof LineElement)
            {
                if (((LineElement) element).getVertices().length == 0 || ((LineElement) element).getVertices().length > 1)
                {
                    pts.add(((LineElement) element).toGeometry(factory).getCoordinates(), true);
                }
            } else if (element instanceof ArcElement)
            {
                pts.add(((ArcElement) element).toGeometry(factory).getCoordinates(), true);
            }
        }
        return factory.createLineString(pts.toCoordinateArray());
    }
    public double getElementSize()
    {
        return raw[18];
    }
    public boolean isClosed()
    {
        if (isEmpty())
        {
            return false;
        }
        return false;
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.COMPLEXCHAIN);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new ComplexChainElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexElement.java
New file
@@ -0,0 +1,16 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.util.List;
/**
 * ComplexElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 04:17:37
 */
public interface ComplexElement extends List
{
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexShapeElement.java
New file
@@ -0,0 +1,217 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.CoordinateList;
/**
 * ComplexShapeElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 03:45:15
 */
public class ComplexShapeElement extends Element implements ComplexElement, GeometryConverter
{
    private static final Logger logger = Logger.getLogger(ComplexShapeElement.class);
    ArrayList<Element> list = new ArrayList<Element>();
    public ComplexShapeElement(byte[] raw)
    {
        super(raw);
    }
    public int size()
    {
        return list.size();
    }
    public boolean isEmpty()
    {
        return list.isEmpty();
    }
    public boolean contains(Object o)
    {
        return list.contains(o);
    }
    public Iterator iterator()
    {
        return list.iterator();
    }
    public Object[] toArray()
    {
        return list.toArray();
    }
    public boolean add(Object o)
    {
        return list.add((Element) o);
    }
    public boolean remove(Object o)
    {
        return list.remove(o);
    }
    public boolean addAll(Collection c)
    {
        return list.addAll(c);
    }
    public boolean addAll(int index, Collection c)
    {
        return list.addAll(index, c);
    }
    public void clear()
    {
        list.clear();
    }
    public Object get(int index)
    {
        return list.get(index);
    }
    public Object set(int index, Object element)
    {
        return list.set(index, (Element) element);
    }
    public void add(int index, Object element)
    {
        list.add(index, (Element) element);
    }
    public Object remove(int index)
    {
        return list.remove(index);
    }
    public int indexOf(Object o)
    {
        return list.indexOf(o);
    }
    public int lastIndexOf(Object o)
    {
        return list.lastIndexOf(o);
    }
    public ListIterator listIterator()
    {
        return list.listIterator();
    }
    public ListIterator listIterator(int index)
    {
        return list.listIterator(index);
    }
    public List subList(int fromIndex, int toIndex)
    {
        return list.subList(fromIndex, toIndex);
    }
    public boolean retainAll(Collection c)
    {
        return list.retainAll(c);
    }
    public boolean removeAll(Collection c)
    {
        return list.removeAll(c);
    }
    public boolean containsAll(Collection c)
    {
        return list.containsAll(c);
    }
    public Object[] toArray(Object[] a)
    {
        return list.toArray(a);
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        ArrayList<Geometry> list = new ArrayList<Geometry>();
        for (ListIterator it = listIterator(); it.hasNext(); )
        {
            Element element = (Element) it.next();
            if (element instanceof ShapeElement)
            {
                if( ((ShapeElement) element).getVerticeSize() == 0 || ((ShapeElement) element).getVerticeSize() > 1)
                {
                  list.add(((ShapeElement) element).toGeometry(factory));
                }
            }
            else if (element instanceof LineStringElement)
            {
               if( ((LineStringElement) element).getVerticeSize() == 0 || ((LineStringElement) element).getVerticeSize() > 1)
               {
                 list.add(((LineStringElement) element).toGeometry(factory));
               }
            } else if (element instanceof LineElement)
            {
               if( ((LineElement) element).getVertices().length == 0 || ((LineElement) element).getVertices().length > 1 )
               {
                 list.add(((LineElement) element).toGeometry(factory));
               }
            } else if (element instanceof ArcElement)
            {
            }
        }
        CoordinateList pts = new CoordinateList();
        for (Geometry geom : list)
        {
            pts.add(geom.getCoordinates(), true);
        }
        return factory.createLinearRing(pts.toCoordinateArray());
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.COMPLEXSHAPE);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new ComplexShapeElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7Exception.java
New file
@@ -0,0 +1,24 @@
package com.ximple.io.dgn7;
public class Dgn7Exception extends Exception
{
    public Dgn7Exception()
    {
    }
    public Dgn7Exception(String s)
    {
        super(s);
    }
    public Dgn7Exception(String s, Throwable throwable)
    {
        super(s, throwable);
    }
    public Dgn7Exception(Throwable throwable)
    {
        super(throwable);
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7OracleReader.java
New file
@@ -0,0 +1,243 @@
package com.ximple.io.dgn7;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import org.apache.log4j.Logger;
import oracle.jdbc.OracleConnection;
import oracle.sql.BLOB;
/**
 * Dgn7OracleReader
 * User: Ulysses
 * Date: 2007/10/24
 * Time: ¤U¤È 01:01:08
 */
public class Dgn7OracleReader implements Iterator<Element>
{
    private final static Logger logger = Logger.getLogger(Dgn7OracleReader.class);
    private String _sql;
    private String _fieldName;
    private Connection _connection;
    private ResultSet _resultSet;
    private static final int FETCHSIZE = 20;
    private Element _element;
    public Dgn7OracleReader(String sql, String fieldName, OracleConnection connection)
    {
        this._sql = sql;
        this._fieldName = fieldName;
        this._connection = connection;
    }
    public String getSql()
    {
        return _sql;
    }
    public void setSql(String sql)
    {
        this._sql = sql;
    }
    public String getFieldName()
    {
        return _fieldName;
    }
    public void setFieldName(String fieldName)
    {
        this._fieldName = fieldName;
    }
    public boolean hasNext()
    {
        if (_resultSet == null)
        {
            try
            {
                initializeReader();
            } catch (SQLException e)
            {
                throw new RuntimeException("initialize oralce error.", e);
            } catch (Dgn7Exception e)
            {
                throw new RuntimeException("initialize oralce error.", e);
            }
        }
        return _element != null;
    }
    public Element next()
    {
        Element result = _element;
        try
        {
            fetchElement();
        } catch (SQLException e)
        {
            throw new RuntimeException("Error:" + e.getMessage(), e);
        } catch (Dgn7Exception e)
        {
            throw new RuntimeException("Error:" + e.getMessage(), e);
        }
        return result;
    }
    public void remove()
    {
        throw new RuntimeException("Not Support this method.");
    }
    private boolean initializeReader() throws SQLException, Dgn7Exception
    {
        if (_resultSet != null) return true;
        Statement stmtSrc = _connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        stmtSrc.setFetchSize(FETCHSIZE);
        _resultSet = stmtSrc.executeQuery(_sql);
        fetchElement();
        return true;
    }
    private boolean fetchElement() throws SQLException, Dgn7Exception
    {
        if (_resultSet.next())
        {
            byte[] raw = null;
            Object value = _resultSet.getObject(this._fieldName);
            if (value instanceof BLOB)
            {
                BLOB blob = (BLOB) value;
                try
                {
                    raw = getBytesFromBLOB(blob);
                } catch (IOException e)
                {
                    throw new Dgn7Exception("IOError", e);
                }
                blob.close();
            } else if (value instanceof byte[])
            {
                raw = (byte[]) value;
            }
            if (raw == null)
            {
                _element = null;
                return false;
            }
            ByteBuffer buffer = ByteBuffer.wrap(raw);
            buffer.order(ByteOrder.LITTLE_ENDIAN);
            short signature = buffer.getShort();
            // byte type = (byte) (buffer.get() & 0x7f);
            byte type = (byte) ((signature >>> 8) & 0x007f);
            // silly Bentley say contentLength is in 2-byte words
            // and ByteByffer uses bytes.
            // track the record location
            int elementLength = (buffer.getShort() * 2) + 4;
            ElementType recordType = ElementType.forID(type);
            IElementHandler handler = recordType.getElementHandler();
            _element = (Element) handler.read(buffer, signature, elementLength);
            if (recordType.isComplexElement() && (elementLength < raw.length))
            {
                int offset = elementLength;
                while (offset < (raw.length - 4))
                {
                    buffer.position(offset);
                    signature = buffer.getShort();
                    type = (byte) ((signature >>> 8) & 0x007f);
                    elementLength = (buffer.getShort() * 2) + 4;
                    if (raw.length < (offset + elementLength))
                    {
                        System.out.println("Length not match:" + offset +":"+ buffer.position() +":"+buffer.limit());
                        break;
                    }
                    recordType = ElementType.forID(type);
                    handler = recordType.getElementHandler();
                    if (handler != null)
                    {
                        Element subElement = (Element) handler.read(buffer, signature, elementLength);
                        ((ComplexElement) _element).add(subElement);
                        offset += elementLength;
                    } else
                    {
                        byte[] remain = new byte[buffer.remaining()];
                        System.arraycopy(raw, offset, remain, 0, buffer.remaining());
                        for (int i = 0; i < remain.length; i++)
                        {
                            if (remain[i] != 0)
                            {
                                logger.info("fetch element has some error. index=" + (offset + i) + ":value=" + remain[i]);
                                System.out.println("fetch element has some error. index=" + (offset + i) + ":value=" + remain[i]);
                            }
                        }
                        break;
                    }
                }
            }
        } else
        {
            _element = null;
            return false;
        }
        return true;
    }
    protected static byte[] getBytesFromBLOB(BLOB blob) throws SQLException, IOException
    {
        byte[] raw;
        // BLOB        blob        = (BLOB) rs.getBlob(1);
        int optimalSize = blob.getChunkSize();
        byte[] chunk = new byte[optimalSize];
        InputStream is = blob.getBinaryStream(0);
        ByteBuffer buffer = null;    // ByteBuffer.allocate(optimalSize);
        int len;
        try
        {
            while ((len = (is.read(chunk))) != -1)
            {
                if (buffer != null)
                {
                    buffer.limit(buffer.limit() + len);
                } else
                {
                    buffer = ByteBuffer.allocate(len);
                }
                buffer.put(chunk);
            }
            is.close();
            assert buffer != null;
            buffer.position(0);
            raw = buffer.array();
        } catch (IOException e)
        {
            e.printStackTrace();
            throw e;
        }
        return raw;
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileException.java
New file
@@ -0,0 +1,24 @@
package com.ximple.io.dgn7;
public class Dgn7fileException extends Dgn7Exception
{
    public Dgn7fileException()
    {
    }
    public Dgn7fileException(String message)
    {
        super(message);
    }
    public Dgn7fileException(String message, Throwable cause)
    {
        super(message, cause);
    }
    public Dgn7fileException(Throwable cause)
    {
        super(cause);
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileHeader.java
New file
@@ -0,0 +1,58 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import com.vividsolutions.jts.util.Assert;
/**
 * Dgn7fileHeader
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/17 ¤U¤È 01:21:00
 */
public class Dgn7fileHeader
{
    private short  elmtype;
    private byte[] raw;
    public Dgn7fileHeader()
    {
    }
    public void read(ByteBuffer file, boolean strict) throws IOException
    {
        file.order(ByteOrder.LITTLE_ENDIAN);
        elmtype = file.getShort();
        short wtf    = file.getShort();
        int   length = (wtf * 2);
        if (file.remaining() != (length))
        {
            Assert.shouldNeverReachHere();
        }
        raw = new byte[length];
        file.get(raw, 0, file.remaining());
    }
    public String toString()
    {
        return "Dgn7fileHeader{" + "raw=" + ((raw == null) ? "null" : raw.length) + '}';
    }
    public int size()
    {
        if (raw == null)
        {
            return 0;
        }
        return raw.length + 4;
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java
New file
@@ -0,0 +1,722 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.util.DgnUtility;
/**
 * Dgn7fileReader
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/17 ¤U¤È 01:24:10
 */
public class Dgn7fileReader
{
    private static final Logger logger = LogManager.getLogger(Dgn7fileReader.class);
    private Dgn7fileHeader      header;
    private ReadableByteChannel channel;
    ByteBuffer                  buffer;
    private ElementType         fileElementType = ElementType.UNDEFINED;
    private ByteBuffer          headerTransfer;
    private final Record        record = new Record();
    private final boolean       randomAccessEnabled;
    private Lock                lock;
    private boolean             useMemoryMappedBuffer;
    private long                currentOffset = 0L;
    private StreamLogging       streamLogger  = new StreamLogging("Shapefile Reader");
    private int                 maxElementId  = 0;
    public Dgn7fileReader(ReadableByteChannel channel, boolean strict, boolean useMemoryMapped, Lock lock)
        throws IOException, Dgn7fileException
    {
        this.channel               = channel;
        this.useMemoryMappedBuffer = useMemoryMapped;
        streamLogger.open();
        randomAccessEnabled = channel instanceof FileChannel;
        this.lock           = lock;
        lock.lockRead();
        init(strict);
    }
    public Dgn7fileReader(ReadableByteChannel channel, Lock lock) throws IOException, Dgn7fileException
    {
        this(channel, true, true, lock);
    }
    // ensure the capacity of the buffer is of size by doubling the original
    // capacity until it is big enough
    // this may be naiive and result in out of MemoryError as implemented...
    public static ByteBuffer ensureCapacity(ByteBuffer buffer, int size, boolean useMemoryMappedBuffer)
    {
        // This sucks if you accidentally pass is a MemoryMappedBuffer of size
        // 80M
        // like I did while messing around, within moments I had 1 gig of
        // swap...
        if (buffer.isReadOnly() || useMemoryMappedBuffer)
        {
            return buffer;
        }
        int limit = buffer.limit();
        while (limit < size)
        {
            limit *= 2;
        }
        if (limit != buffer.limit())
        {
            // if (record.ready) {
            buffer = ByteBuffer.allocateDirect(limit);
            // }
            // else {
            // throw new IllegalArgumentException("next before hasNext");
            // }
        }
        return buffer;
    }
    // for filling a ReadableByteChannel
    public static int fill(ByteBuffer buffer, ReadableByteChannel channel) throws IOException
    {
        int r = buffer.remaining();
        // channel reads return -1 when EOF or other error
        // because they a non-blocking reads, 0 is a valid return value!!
        while ((buffer.remaining() > 0) && (r != -1))
        {
            r = channel.read(buffer);
        }
        if (r == -1)
        {
            buffer.limit(buffer.position());
        }
        return r;
    }
    public static Dgn7fileHeader readHeader(ReadableByteChannel channel, boolean strict) throws IOException
    {
        ByteBuffer buffer = ByteBuffer.allocateDirect(4);
        if (fill(buffer, channel) == -1)
        {
            throw new EOFException("Premature end of header");
        }
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        int        length = buffer.getShort(2) * 2;
        ByteBuffer old    = buffer;
        old.position(0);
        // ensure enough capacity for one more record header
        buffer = ByteBuffer.allocateDirect(length + 4);
        buffer.put(old);
        if (fill(buffer, channel) == -1)
        {
            throw new EOFException("Premature end of header");
        }
        buffer.position(0);
        Dgn7fileHeader header = new Dgn7fileHeader();
        header.read(buffer, strict);
        return header;
    }
    public Dgn7fileHeader getHeader()
    {
        return header;
    }
    public void close() throws IOException
    {
        lock.unlockRead();
        if (channel.isOpen())
        {
            channel.close();
            streamLogger.close();
        }
        if (buffer instanceof MappedByteBuffer)
        {
            NIOUtilities.clean(buffer);
        }
        channel = null;
        header  = null;
    }
    public boolean supportsRandomAccess()
    {
        return randomAccessEnabled;
    }
    public Record nextElement() throws IOException, Dgn7fileException
    {
        // need to update position
        buffer.position(this.toBufferOffset(record.end));
        // record header is big endian
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        // read shape record header
        int   recordNumber = ++maxElementId;
        short signature    = buffer.getShort();
        // byte type = (byte) (buffer.get() & 0x7f);
        byte type = (byte) ((signature >>> 8) & 0x007f);
        // silly Bentley say contentLength is in 2-byte words
        // and ByteByffer uses bytes.
        // track the record location
        int elementLength = (buffer.getShort() * 2) + 4;
        if (!buffer.isReadOnly() &&!useMemoryMappedBuffer)
        {
            // capacity is less than required for the record
            // copy the old into the newly allocated
            if (buffer.capacity() < elementLength)
            {
                this.currentOffset += buffer.position();
                ByteBuffer old = buffer;
                // ensure enough capacity for one more record header
                buffer = ensureCapacity(buffer, elementLength, useMemoryMappedBuffer);
                buffer.put(old);
                fill(buffer, channel);
                buffer.position(0);
            } else
            // remaining is less than record length
            // compact the remaining data and read again,
            // allowing enough room for one more record header
            if (buffer.remaining() < elementLength)
            {
                this.currentOffset += buffer.position();
                buffer.compact();
                fill(buffer, channel);
                buffer.position(0);
            }
        }
        // shape record is all little endian
        // buffer.order(ByteOrder.LITTLE_ENDIAN);
        // read the type, handlers don't need it
        ElementType recordType = ElementType.forID(type);
        logger.debug("nextElement at " + this.toBufferOffset(record.end) + ":type=" + type);
        // this usually happens if the handler logic is bunk,
        // but bad files could exist as well...
        /*
         * if (recordType != ElementType.NULL && recordType != fileElementType)
         * {
         *   throw new IllegalStateException("ShapeType changed illegally from " + fileElementType + " to " + recordType);
         * }
         */
        // peek at bounds, then reset for handler
        // many handler's may ignore bounds reading, but we don't want to
        // second guess them...
        buffer.mark();
        if (recordType.isMultiPoint())
        {
            int lowCoorX = buffer.getInt();
            lowCoorX    = DgnUtility.convertFromDGN(lowCoorX);
            record.minX = DgnUtility.converUnitToCoord(lowCoorX);
            int lowCoorY = buffer.getInt();
            lowCoorY    = DgnUtility.convertFromDGN(lowCoorY);
            record.minY = DgnUtility.converUnitToCoord(lowCoorY);
            int lowCoorZ = buffer.getInt();
            lowCoorZ    = DgnUtility.convertFromDGN(lowCoorZ);
            record.minZ = DgnUtility.converUnitToCoord(lowCoorZ);
            int highCoorX = buffer.getInt();
            highCoorX   = DgnUtility.convertFromDGN(highCoorX);
            record.maxX = DgnUtility.converUnitToCoord(highCoorX);
            int highCoorY = buffer.getInt();
            highCoorY   = DgnUtility.convertFromDGN(highCoorY);
            record.maxY = DgnUtility.converUnitToCoord(highCoorY);
            int highCoorZ = buffer.getInt();
            highCoorZ   = DgnUtility.convertFromDGN(highCoorZ);
            record.maxZ = DgnUtility.converUnitToCoord(highCoorZ);
        }
        buffer.reset();
        record.offset = record.end;
        // update all the record info.
        record.length    = elementLength;
        record.signature = signature;
        record.number    = recordNumber;
        // remember, we read one int already...
        record.end = this.toFileOffset(buffer.position()) + elementLength - 4;
        // record.end = this.toFileOffset(buffer.position()) + elementLength;
        // mark this position for the reader
        record.start = buffer.position();
        // clear any cached record
        record.handler = recordType.getElementHandler();
        record.element = null;
        return record;
    }
    public void goTo(int offset) throws IOException, UnsupportedOperationException
    {
        if (randomAccessEnabled)
        {
            if (this.useMemoryMappedBuffer)
            {
                buffer.position(offset);
            } else
            {
                /*
                 *     Check to see if requested offset is already loaded; ensure
                 *     that record header is in the buffer
                 */
                if ((this.currentOffset <= offset) && (this.currentOffset + buffer.limit() >= offset + 4))
                {
                    buffer.position(this.toBufferOffset(offset));
                } else
                {
                    FileChannel fc = (FileChannel) this.channel;
                    fc.position(offset);
                    this.currentOffset = offset;
                    buffer.position(0);
                    fill(buffer, fc);
                    buffer.position(0);
                }
            }
            int oldRecordOffset = record.end;
            record.end = offset;
            try
            {
                hasNext();
            } catch (IOException ioe)
            {
                record.end = oldRecordOffset;
                throw ioe;
            }
        } else
        {
            throw new UnsupportedOperationException("Random Access not enabled");
        }
    }
    public Record elementAt(int offset) throws IOException, UnsupportedOperationException, Dgn7fileException
    {
        if (randomAccessEnabled)
        {
            this.goTo(offset);
            return nextElement();
        }
        throw new UnsupportedOperationException("Random Access not enabled");
    }
    public boolean hasNext() throws IOException
    {
        // mark current position
        int position = buffer.position();
        // ensure the proper position, regardless of read or handler behavior
        try
        {
            buffer.position(this.toBufferOffset(record.end));
        } catch (IllegalArgumentException e)
        {
            logger.warn("position=" + this.toBufferOffset(record.end), e);
            return false;
        }
        // no more data left
        if (buffer.remaining() < 4)
        {
            return false;
        }
        // looks good
        boolean hasNext = true;
        short   type    = buffer.getShort();
        if (type == -1)
        {
            hasNext = false;
        }
        // reset things to as they were
        buffer.position(position);
        return hasNext;
    }
    private void init(boolean strict) throws IOException, Dgn7fileException
    {
        header = readHeader(channel, strict);
        // fileElementType = header.getElementType();
        // handler = fileElementType.getElementHandler();
        // recordHeader = ByteBuffer.allocateDirect(4);
        // recordHeader.order(ByteOrder.BIG_ENDIAN);
        // if (handler == null)
        // {
        // throw new IOException("Unsuported shape type:" + fileElementType);
        // }
        if ((channel instanceof FileChannel) && useMemoryMappedBuffer)
        {
            FileChannel fc = (FileChannel) channel;
            buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
            // buffer.position(100);
            buffer.position(header.size());
            this.currentOffset = 0;
        } else
        {
            // force useMemoryMappedBuffer to false
            this.useMemoryMappedBuffer = false;
            // start with 8K buffer
            buffer = ByteBuffer.allocateDirect(8 * 1024);
            fill(buffer, channel);
            buffer.flip();
            this.currentOffset = header.size();
        }
        headerTransfer = ByteBuffer.allocate(4);
        headerTransfer.order(ByteOrder.LITTLE_ENDIAN);
        // make sure the record end is set now...
        record.end = toFileOffset(buffer.position());
    }
    private int toBufferOffset(int offset)
    {
        return (int) (offset - currentOffset);
    }
    private int toFileOffset(int offset)
    {
        return (int) (currentOffset + offset);
    }
    public int getCount(int count) throws Dgn7fileException
    {
        try
        {
            if (channel == null)
            {
                return -1;
            }
            count = 0;
            for (int tmp = readElement(); tmp != -1; tmp = readElement())
            {
                count += tmp;
            }
        } catch (IOException ioe)
        {
            count = -1;
            // What now? This seems arbitrarily appropriate !
            throw new Dgn7fileException("Problem reading dgnfile record", ioe);
        }
        return count;
    }
    public int getCount() throws Dgn7fileException
    {
        return getCount(0);
    }
    private int readElement() throws IOException
    {
        if (!fillBuffer())
        {
            return -1;
        }
        // burn the record number
        buffer.getInt();
        if (!fillBuffer())
        {
            return -1;
        }
        int recordlength = buffer.getInt() * 2;
        // Going to read the first 4 bytes of the record so
        // subtract that from the record length
        recordlength -= 4;
        if (!fillBuffer())
        {
            return -1;
        }
        // read record type (used to determine if record is a null record)
        int type = buffer.getInt();
        // go to end of record
        while (buffer.limit() < buffer.position() + recordlength)
        {
            recordlength -= buffer.limit() - buffer.position();
            buffer.clear();
            if (channel.read(buffer) < 1)
            {
                return -1;
            }
        }
        buffer.position(buffer.position() + recordlength);
        // return 0 if record is null. Null records should be counted.
        if (type == 0)
        {
            // this is a null feature
            return 0;
        }
        return 1;
    }
    private boolean fillBuffer() throws IOException
    {
        int result = 1;
        if (buffer.limit() <= buffer.position() + 4)
        {
            result = fill(buffer, channel);
        }
        return result > 0;
    }
    public static void main(String[] args)
    {
        JFileChooser jfc = new JFileChooser("D:/TEMP");
        File         f   = null;
        int          r   = jfc.showOpenDialog(new JFrame());
        if (r == JFileChooser.APPROVE_OPTION)
        {
            try
            {
                f = jfc.getSelectedFile();
                FileChannel    channel = new FileInputStream(f).getChannel();
                Dgn7fileReader reader  = new Dgn7fileReader(channel, new Lock());
                System.out.println(reader.getHeader().toString());
                GeometryFactory factory = new GeometryFactory();
                int             count, size;
                count = 0;
                size  = 0;
                try
                {
                    Element lastComplex = null;
                    while (reader.hasNext())
                    {
                        size++;
                        Dgn7fileReader.Record record = reader.nextElement();
                        if (record.element() != null)
                        {
                            Element     element = (Element) record.element();
                            ElementType type    = element.getElementType();
                            if ((!type.isComplexElement()) && (!element.isComponentElement()))
                            {
                                if (lastComplex != null)
                                {
                                    // @todo add process in here
                                    count++;
                                    lastComplex = null;
                                }
                                // @todo add process in here
                                count++;
                            } else if (element.isComponentElement())
                            {
                                if (lastComplex != null)
                                {
                                    ((ComplexElement) lastComplex).add(element);
                                }
                            } else if (type.isComplexElement())
                            {
                                if (lastComplex == null)
                                {
                                    lastComplex = element;
                                } else
                                {
                                    // @todo add process in here
                                    count++;
                                    lastComplex = element;
                                }
                            }
                        }
                    }
                } catch (IOException e)
                {
                    logger.warn("Stop read dgn file", e);
                } catch (Dgn7fileException e)
                {
                    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                } finally
                {
                    reader.close();
                }
                System.out.println("count=" + count + " size=" + size);
                // reader.close();
            } catch (IOException ioe)
            {
                System.out.println(ioe);
                ioe.printStackTrace();
            } catch (Dgn7fileException e)
            {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        System.exit(0);
    }
    public final class Record
    {
        int   length;
        int   number = 0;
        int   offset;           // Relative to the whole file
        int   start     = 0;    // Relative to the current loaded buffer
        short signature = 0;
        /**
         * The minimum X value.
         */
        public double minX;
        /**
         * The minimum Y value.
         */
        public double minY;
        /**
         * The minimum Z value.
         */
        public double minZ;
        /**
         * The maximum X value.
         */
        public double maxX;
        /**
         * The maximum Y value.
         */
        public double maxY;
        /**
         * The maximum Z value.
         */
        public double maxZ;
        // ElementType type;
        int             end     = 0;    // Relative to the whole file
        Object          element = null;
        IElementHandler handler;
        public Object element()
        {
            if (element == null)
            {
                buffer.position(start);
                buffer.order(ByteOrder.LITTLE_ENDIAN);
                if (handler == null)
                {
                    return null;
                }
                element = handler.read(buffer, signature, length);
            }
            return element;
        }
        public int offset()
        {
            return offset;
        }
        /**
         * A summary of the record.
         */
        public String toString()
        {
            return "Record " + number + " length " + length + " bounds " + minX + "," + minY + " " + maxX + "," + maxY;
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java
New file
@@ -0,0 +1,274 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import com.vividsolutions.jts.geom.Envelope;
import com.ximple.util.DgnUtility;
/**
 * Record
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤W¤È 11:14:50
 */
public class Element
{
    public static final int CONSTRUCTION_CLASS      = 0;
    public static final int CONSTRUCTION_RULE_CLASS = 0;
    public static final int DIMENSION_CLASS         = 0;
    public static final int LINEAR_PATTERNED_CLASS  = 0;
    public static final int MAX_ELEMENT_SIZE        = 0;
    public static final int MAX_VERTICES            = 100;
    public static final int PATTERN_AREA            = 0;
    public static final int PATTERN_COMPONENT_CLASS = 0;
    public static final int PATTERN_CROSSHATCH      = 0;
    public static final int PATTERN_HATCH           = 0;
    public static final int PRIMARY_CLASS           = 0;
    public static final int PRIMARY_RULE_CLASS      = 0;
    protected short[]       raw;
    protected byte          attrOffset = 0;
    protected ByteBuffer    rawBuffer;
    public Element(byte[] raw)
    {
        // this.raw = raw;
        this.raw = new short[raw.length / 2];
        rawBuffer = ByteBuffer.wrap(raw);
        rawBuffer.order(ByteOrder.LITTLE_ENDIAN);
        rawBuffer.asShortBuffer().get(this.raw);
    }
    public int getLineStyle()
    {
        return 0;
    }
    public Envelope getRange()
    {
        int lowCoorX = ((raw[3] << 16) & 0xffff0000) + (raw[2] & 0x0000ffff);
        lowCoorX = DgnUtility.convertFromDGN(lowCoorX);
        int lowCoorY = ((raw[5] << 16) & 0xffff0000) + (raw[4] & 0x0000ffff);
        lowCoorY = DgnUtility.convertFromDGN(lowCoorY);
        int highCoorX = ((raw[9] << 16) & 0xffff0000) + (raw[8] & 0x0000ffff);
        highCoorX = DgnUtility.convertFromDGN(highCoorX);
        int highCoorY = ((raw[11] << 16) & 0xffff0000) + (raw[10] & 0x0000ffff);
        highCoorY = DgnUtility.convertFromDGN(highCoorY);
        return new Envelope(DgnUtility.converUnitToCoord(lowCoorX), DgnUtility.converUnitToCoord(highCoorX),
                            DgnUtility.converUnitToCoord(lowCoorY), DgnUtility.converUnitToCoord(highCoorY));
    }
    public boolean isComponentElement()
    {
        return (short) ((raw[0] >>> 7) & 0x0001) == 1;
    }
    public boolean removeUserAttributeData(int iLinkageId)
    {
        return true;
    }
    public boolean removeUserAttributeData(int iLinkageId, int iLinkageIndex)
    {
        return true;
    }
    public boolean isDeleted()
    {
        return (short) ((raw[0] >>> 15) & 0x0001) == 1;
    }
    public int getColorIndex()
    {
        return ((raw[17] >>> 8) & 0x00ff);
    }
    public int getType()
    {
        return ((raw[0] >>> 8) & 0x007f);
    }
    public ElementType getElementType()
    {
        return ElementType.forID(getType());
    }
    public int getLevelIndex()
    {
        return (raw[0] & 0x003f);
    }
    public int getWeight()
    {
        return ((raw[17] >>> 3) & 0x001f);
    }
    public void addUserAttributeData(byte[] pDataBlock, Class dataClass, int iLinkageId) throws Element.Exception
    {
    }
    public void addUserAttributeData(byte[] pDataBlock, int iLinkageId, Object oDataDef) throws Element.Exception
    {
    }
    public boolean hasUserAttributeData()
    {
        if (raw[15] <= 0)
        {
            return false;
        }
        short index = (short) (raw[15] + 16);
        if (index == -1)
        {
            return false;
        }
        return true;
    }
    public List<UserAttributeData> getUserAttributeData()
    {
        short[] data;
        short   length, nextAttribute;
        if (raw[15] <= 0)
        {
            return new ArrayList<UserAttributeData>();
        }
        short index = (short) (raw[15] + 16 + attrOffset);
        if (index == -1)
        {
            return null;
        }
        ArrayList<UserAttributeData> aLinkageSet = new ArrayList<UserAttributeData>();
        while (index < raw.length)
        {
            length = (short) (raw[index] & (short) 0x00ff);
            if (length == 0)
            {
                break;
            }
            nextAttribute = (short) (index + length + 1);
            data          = new short[length];
            System.arraycopy(raw, index + 1, data, 0, length);
            if (data[0] == (short) 0x0020)
            {
                aLinkageSet.add(new FrammeAttributeData(data));
            } else
            {
                aLinkageSet.add(new UserAttributeData(data));
            }
            index = nextAttribute;
        }
        return aLinkageSet;
    }
    public void getUserAttributeData(byte[] pDataBlock, Class dataClass, int iLinkageId, int iLinkageIndex)
    {
    }
    public void getUserAttributeData(byte[] pDataBlock, int iLinkageId, Object oDataDef)
    {
    }
    public static class Exception extends java.lang.Exception
    {
        public Exception()
        {
        }
        // Constructs an Record.Exception with no detail message.
        public Exception(String oStrMessage)
        {
            super(oStrMessage);
        }
    }
    protected static int getOffsetPosition(int offset)
    {
        return offset * 2;
    }
    public static class ElementHandler implements IElementHandler
    {
        ElementType elementType;
        public ElementHandler(ElementType elementType)
        {
            this.elementType = elementType;
        }
        public ElementType getElementType()
        {
            return elementType;
        }
        public Object read(ByteBuffer buffer, short signature, int length)
        {
            byte[] dst = new byte[length];
            try
            {
                buffer.get(dst, 4, dst.length - 4);
            } catch (BufferUnderflowException exception)
            {
                throw exception;
            }
            ByteBuffer tmpBuffer = ByteBuffer.wrap(dst);
            tmpBuffer.order(ByteOrder.LITTLE_ENDIAN);
            tmpBuffer.position(0);
            tmpBuffer.putShort(signature);
            tmpBuffer.putShort((short) ((length / 2) - 2));
            /*
            ShortBuffer sbuffer = tmpBuffer.asShortBuffer();
            short[] rawMem = new short[(length / 2)];
            sbuffer.get(rawMem, 2, rawMem.length - 2);
            rawMem[0] = signature;
            rawMem[1] = (short) ((length / 2) - 2);
            */
            Element elm = createElement(dst);
            return elm;
        }
        public void write(ByteBuffer buffer, Object element)
        {
            buffer.put(((Element) element).rawBuffer);
        }
        public int getLength(Object element)
        {
            return ((Element) element).raw.length;
        }
        protected Element createElement(byte[] raw)
        {
            return new Element(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java
New file
@@ -0,0 +1,385 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
/*----------------------------------------------------------------------+
|                                                                       |
|   Type        Description                                             |
|    1          Cell Library Header                                     |
|    2          Cell (complex)                                          |
|    3          Line                                                    |
|    4          Line String                                             |
|    5          Group Data                                              |
|    6          Shape                                                   |
|    7          Text Node (complex)                                     |
|    8          Digitizer Setup Data                                    |
|    9          Design File Header if level 8                           |
|    10         Level Symbology                                         |
|    11         Curve                                                   |
|    12         Complex String (complex)                                |
|    13         Conic                                                   |
|    14         Complex Shape (complex)                                 |
|    15         Ellipse                                                 |
|    16         Arc                                                     |
|    17         Text                                                    |
|    18         Surface (complex)                                       |
|    19         Solid (complex)                                         |
|    20         not used                                                |
|    21         B-Spline Pole                                           |
|    22         Point String                                            |
|    23         Circular Truncated Cone                                 |
|    24         B-Spline Surface (complex)                              |
|    25         B-Spline Surface boundary                               |
|    26         B-Spline Knot Record                                   |
|    27         B-Spline Curve (complex)                                |
|    28         B-Spline Weight Factor                                  |
|    33         Dimension Record                                       |
|    34         Shared Cell Definition Record                          |
|    35         Shared Cell Record                                     |
|    36         Multiline Record                                       |
|    37         Attribute Record                                       |
|    38         DgnStore Component                                      |
|    39         DgnStore Header                                         |
|    66         MicroStation Application                                |
|    87         Raster Header                                           |
|    88         Raster Component                                        |
|    90         Raster Reference Attachment                             |
|    91         Raster Reference Component                              |
|    92         Raster Hierarchy Record                                |
|    93         Raster Hierarchy Component                              |
|    94         Raster Frame Record                                    |
|    95         Table Entry Record                                     |
|    96         Table Header Record                                    |
|    97         View Group Record                                      |
|    98         View Record                                            |
|    99         Level Mask Record                                      |
|    100        Reference Attach Record                                |
|    101        Matrix Header                                           |
|    102        Matrix Int Data                                         |
|    103        Matrix Double Data                                      |
|    105        Mesh Header                                             |
|    106        Extended Record (graphic) (complex)                    |
|    107        Extended Record (non-graphic) (complex)                |
|    108        Reference Override Record                              |
|    110        Named Group Header                                      |
|    111        Named Group Component                                   |
|                                                                       |
+----------------------------------------------------------------------*/
/**
 * ElementType
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/17 ¤U¤È 01:26:49
 */
public final class ElementType
{
    /**
     * Represents a Null shape (id = 0).
     */
    public static final ElementType NULL = new ElementType(0, "Null");
    /**
     * Represents a Line shape (id = 3).
     */
    public static final ElementType LINE = new ElementType(3, "Line");
    /**
     * Represents a LineString shape (id = 4).
     */
    public static final ElementType LINESTRING = new ElementType(4, "LineString");
    /**
     * Represents a Shape shape (id = 6).
     */
    public static final ElementType SHAPE = new ElementType(6, "Shape");
    /**
     * Represents an TextNode shape (id = 7).
     */
    public static final ElementType TEXTNODE = new ElementType(7, "TextNode");
    /**
     * Represents an IGDSDIGITIZER shape (id = 8).
     */
    public static final ElementType IGDSDIGITIZER = new ElementType(8, "IGDSDigitizer");
    /**
     * Represents an TCB shape (id = 9).
     */
    public static final ElementType TCB = new ElementType(9, "Tcb");
    /**
     * Represents a LevelSymbology shape (id = 5).
     */
    public static final ElementType LEVELSYMBOLOGY = new ElementType(10, "LevelSymbology");
    /**
     * Represents a ComplexChain shape (id = 15).
     */
    public static final ElementType COMPLEXCHAIN = new ElementType(12, "ComplexChain");
    /**
     * Represents a ComplexShape shape (id = 25).
     */
    public static final ElementType COMPLEXSHAPE = new ElementType(14, "ComplexShape");
    /**
     * Represents a Ellipse shape (id = 8).
     */
    public static final ElementType ELLIPSE = new ElementType(15, "Ellipse");
    /**
     * Represents a Arc shape (id = 28).
     */
    public static final ElementType ARC = new ElementType(16, "Arc");
    /**
     * Represents a Arc shape (id = 28).
     */
    public static final ElementType TEXT = new ElementType(17, "Text");
    /**
     * Represents a Arc shape (id = 28).
     */
    public static final ElementType POINTSTRING = new ElementType(22, "PointString");
    /**
     * Represents an Undefined shape (id = -1).
     */
    public static final ElementType UNDEFINED = new ElementType(-1, "Undefined");
    /**
     * The integer id of this ElementType.
     */
    public final int id;
    /**
     * The human-readable name for this ElementType.<br>
     * Could easily use ResourceBundle for internationialization.
     */
    public final String name;
    /**
     * Creates a new instance of ElementType. Hidden on purpose.
     *
     * @param id   The id.
     * @param name The name.
     */
    protected ElementType(int id, String name)
    {
        this.id   = id;
        this.name = name;
    }
    /**
     * Get the name of this ElementType.
     *
     * @return The name.
     */
    public String toString()
    {
        return name;
    }
    /**
     * Is this a multipoint shape? Hint- all shapes are multipoint except NULL,
     * UNDEFINED, and the POINTs.
     *
     * @return true if multipoint, false otherwise.
     */
    public boolean isMultiPoint()
    {
        boolean mp = true;
        if (this == UNDEFINED)
        {
            mp = false;
        } else if (this == NULL)
        {
            mp = false;
        } else if (this == IGDSDIGITIZER)
        {
            mp = false;
        } else if (this == TCB)
        {
            mp = false;
        } else if (this == LEVELSYMBOLOGY)
        {
            mp = false;
        }
        return mp;
    }
    public boolean isComplexElement()
    {
        return id == 2 || id == 7 || id == 12 || id == 14 || id == 18 ||
                id == 19 || id == 106 || id == 107;
    }
    public boolean isPointType()
    {
        return id == 7 || id == 17;
    }
    public boolean isLineType()
    {
        return id == 3 || id == 4 || id == 11 || id == 12 || id == 16;
    }
    public boolean isPolygonType()
    {
        return id == 6 || id == 14;
    }
    public boolean isMultiPointType()
    {
        return id == 3 || id == 4 || id == 6 || id == 11 || id == 12 ||
                id == 13 || id == 14 || id == 15 || id == 16 || id == 22;
    }
    public boolean isArcType()
    {
        return id == 15 || (id == 16);
    }
    /**
     * Determine the ElementType for the id.
     *
     * @param id The id to search for.
     * @return The ElementType for the id.
     */
    public static ElementType forID(int id)
    {
        ElementType t;
        switch (id)
        {
        case 0 :
            t = NULL;
            break;
        case 3 :
            t = LINE;
            break;
        case 4 :
            t = LINESTRING;
            break;
        case 6 :
            t = SHAPE;
            break;
        case 7 :
            t = TEXTNODE;
            break;
        case 8 :
            t = IGDSDIGITIZER;
            break;
        case 9 :
            t = TCB;
            break;
        case 10 :
            t = LEVELSYMBOLOGY;
            break;
        case 12 :
            t = COMPLEXCHAIN;
            break;
        case 14 :
            t = COMPLEXSHAPE;
            break;
        case 15 :
            t = ELLIPSE;
            break;
        case 16 :
            t = ARC;
            break;
        case 17 :
            t = TEXT;
            break;
        default :
            t = UNDEFINED;
            break;
        }
        return t;
    }
    public IElementHandler getElementHandler() throws Dgn7fileException
    {
        IElementHandler handler;
        switch (id)
        {
        case 3 :
            handler = LineElement.ElementHandler.getInstance();
            break;
        case 4 :
            handler = LineStringElement.ElementHandler.getInstance();
            break;
        case 6 :
            handler = ShapeElement.ElementHandler.getInstance();
            break;
        case 7 :
            handler = TextNodeElement.ElementHandler.getInstance();
            break;
        case 8 :
            handler = new Element.ElementHandler(this);
            break;
        case 9 :
            handler = new Element.ElementHandler(this);
            break;
        case 10 :
            handler = new Element.ElementHandler(this);
            break;
        case 12 :
            handler = ComplexChainElement.ElementHandler.getInstance();
            break;
        case 14 :
            handler = ComplexShapeElement.ElementHandler.getInstance();
            break;
        case 15 :
            handler = EllipseElement.ElementHandler.getInstance();
            break;
        case 16 :
            handler = ArcElement.ElementHandler.getInstance();
            break;
        case 17 :
            handler = TextElement.ElementHandler.getInstance();
            break;
        default :
            handler = null;
        }
        return handler;
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/EllipseElement.java
New file
@@ -0,0 +1,211 @@
package com.ximple.io.dgn7;
import java.nio.ByteOrder;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.util.DgnUtility;
public class EllipseElement extends Element implements GeometryConverter
{
    private static final Logger logger = Logger.getLogger(EllipseElement.class);
    public EllipseElement(byte[] raw)
    {
        super(raw);
    }
    public double getStartAngle()
    {
        return 0.0;
    }
    public void setStartAngle(double value)
    {
    }
    public double getSweepAngle()
    {
        return 360.0;
    }
    public void setSweepAngle(double value)
    {
    }
    public double getPrimary()
    {
        rawBuffer.position(18 * 2);
        ByteOrder bo = rawBuffer.order();
        rawBuffer.order(ByteOrder.BIG_ENDIAN);
        byte[] primary = new byte[8];
        rawBuffer.get(primary);
        rawBuffer.order(bo);
        return DgnUtility.convertDGNToIEEEDouble(primary) / 1000.0;
    }
    public void setPrimary(double value)
    {
        double temp = value * 1000.0;
        short[] primary = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(primary, 0, raw, 18, 4);
    }
    public double getSecondary()
    {
        rawBuffer.position(22 * 2);
        ByteOrder bo = rawBuffer.order();
        rawBuffer.order(ByteOrder.BIG_ENDIAN);
        byte[] secondary = new byte[8];
        rawBuffer.get(secondary);
        rawBuffer.order(bo);
        return DgnUtility.convertDGNToIEEEDouble(secondary) / 1000.0;
    }
    public void setSecondary(double value)
    {
        double temp = value * 1000.0;
        short[] secondary = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(secondary, 0, raw, 22, 4);
    }
    public double getRotationAngle()
    {
        int rotation = (raw[26] << 16 & 0xffff0000);
        rotation |= raw[27] & 0x0000ffff;
        return DgnUtility.converIntToRotation(rotation);
    }
    public void setRotationAngle(double value)
    {
        int angle = DgnUtility.converRotatioToInt(value);
        raw[26] = (short) (angle >> 16 & 0x0000ffff);
        raw[27] = (short) (angle & 0x0000ffff);
    }
    public Coordinate getOrigin()
    {
        rawBuffer.position(28 * 2);
        ByteOrder bo = rawBuffer.order();
        rawBuffer.order(ByteOrder.BIG_ENDIAN);
        byte[] rawValue = new byte[8];
        rawBuffer.get(rawValue); // x
        double dx = DgnUtility.converUnitToCoord(DgnUtility.convertDGNToIEEEDouble(rawValue));
        rawBuffer.get(rawValue); // y
        double dy = DgnUtility.converUnitToCoord(DgnUtility.convertDGNToIEEEDouble(rawValue));
        rawBuffer.order(bo);
        return new Coordinate(dx, dy);
    }
    public void setOrigin(Coordinate value)
    {
        double temp = DgnUtility.converCoordToUnit(value.x);
        short[] x = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(x, 0, raw, 28, 4);
        temp = DgnUtility.converCoordToUnit(value.y);
        short[] y = DgnUtility.convertIEEEDoubleToDGN(temp);
        System.arraycopy(y, 0, raw, 32, 4);
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        double temp = Math.abs(getStartAngle() - getSweepAngle());
        temp /= 4;
        int pts = (temp < 3) ? 3 : (int) temp;
        return factory.createPolygon(factory.createLinearRing(convertToLineString(pts)), null);
    }
    private Coordinate[] convertToLineString(int pts)
    {
        ArrayList<Coordinate> result = new ArrayList<Coordinate>();
        double beta = DgnUtility.converRotationToRadian(-getRotationAngle());
        double startAngle = getStartAngle();
        double sweepAngle = getSweepAngle();
        double endAngle = startAngle + sweepAngle;
        double steps = sweepAngle / pts;
        double current;
        if (sweepAngle < 0)
        {
            for (current = startAngle; current > endAngle; current += steps)
            {
                Coordinate pt = computePointOnArcByAngle(beta, current);
                result.add(pt);
            }
        } else
        {
            for (current = startAngle; current < endAngle; current += steps)
            {
                Coordinate pt = computePointOnArcByAngle(beta, current);
                result.add(pt);
            }
        }
        Coordinate pt = computePointOnArcByAngle(beta, endAngle);
        result.add(pt);
        if (!result.get(0).equals(result.get(result.size() - 1)))
        {
            result.add(result.get(0));
        }
        return result.toArray(new Coordinate[result.size()]);
    }
    private Coordinate computePointOnArcByAngle(double beta, double current)
    {
        double sinbeta = Math.sin(beta);
        double cosbeta = Math.cos(beta);
        Coordinate pt = new Coordinate();
        double alpha = DgnUtility.converRotationToRadian(current);
        double sinalpha = Math.sin(alpha);
        double cosalpha = Math.cos(alpha);
        pt.x = getOrigin().x + (getPrimary() * cosalpha * cosbeta -
                getSecondary() * sinalpha * sinbeta);
        pt.y = getOrigin().y + (getPrimary() * cosalpha * sinbeta +
                getSecondary() * sinalpha * cosbeta);
        return pt;
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.ELLIPSE);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new EllipseElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/FrammeAttributeData.java
New file
@@ -0,0 +1,71 @@
package com.ximple.io.dgn7;
/**
 * FrammeAttributeData
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 06:36:55
 */
public class FrammeAttributeData extends UserAttributeData
{
    public FrammeAttributeData(short id)
    {
        super(id, 7);
    }
    public FrammeAttributeData(short[] src)
    {
        super(src);
    }
    public short getFsc()
    {
        int fsc = _src[3] & 0x0000ffff;
        return (short) fsc;
    }
    public int getUfid()
    {
        int ufid = (int) (_src[2] << 16 & 0xffff0000);
        ufid += _src[1] & 0x0000ffff;
        return ufid;
    }
    public byte getComponentID()
    {
        int cmpid = (int) (_src[5] & 0x000000ff);
        return (byte) cmpid;
    }
    public byte getRuleNo()
    {
        int no = (int) ((_src[5] >> 8) & 0x000000ff);
        return (byte) no;
    }
    public short getStatus()
    {
        int status = (int) (_src[4] & 0x0000ffff);
        return (short) status;
    }
    public short getOccID()
    {
        int occid = (int) (_src[6] & 0x0000ffff);
        return (short) occid;
    }
    public String toString()
    {
        return "FrammeData{" + getFsc() + "," + getUfid() + "," + getComponentID() + "," + getRuleNo() + "," + getStatus() + ","
               + getOccID() + "}";
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/GeometryConverter.java
New file
@@ -0,0 +1,18 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
 * GeometryConverter
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤W¤È 11:38:57
 */
public interface GeometryConverter
{
    public Geometry toGeometry(GeometryFactory factory);
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/IElementHandler.java
New file
@@ -0,0 +1,23 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.nio.ByteBuffer;
/**
 * IElementHandler
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/17 ¤U¤È 01:50:26
 */
public interface IElementHandler
{
    public ElementType getElementType();
    public Object read(ByteBuffer buffer, short signature, int length);
    public void write(ByteBuffer buffer, Object element);
    public int getLength(Object element);
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineElement.java
New file
@@ -0,0 +1,130 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.util.DgnUtility;
/**
 * LineElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤W¤È 11:34:59
 */
public class LineElement extends Element implements GeometryConverter
{
    private static final Logger logger = Logger.getLogger(LineElement.class);
    public LineElement(byte[] raw)
    {
        super(raw);
    }
    public Coordinate getCentroid(double dTolerance)
    {
        return null;
    }
    public Coordinate getEndPoint()
    {
        int endX = ((raw[22] << 16) & 0xffff0000) | (raw[23] & 0x0000ffff);
        int endY = ((raw[24] << 16) & 0xffff0000) | (raw[25] & 0x0000ffff);
        double x = DgnUtility.converUnitToCoord(endX);
        double y = DgnUtility.converUnitToCoord(endY);
        return new Coordinate(x, y);
    }
    public Coordinate getNormal()
    {
        return null;
    }
    public Coordinate getOrigin()
    {
        return null;
    }
    public Coordinate getStartPoint()
    {
        int startX = ((raw[18] << 16) & 0xffff0000);
        startX = startX + (raw[19] & 0x0000ffff);
        double x      = DgnUtility.converUnitToCoord(startX);
        int    startY = ((raw[20] << 16) & 0xffff0000);
        startY = startY + (raw[21] & 0x0000ffff);
        double y = DgnUtility.converUnitToCoord(startY);
        return new Coordinate(x, y);
    }
    public Coordinate getVertex(int index)
    {
        return (index == 0)
               ? getStartPoint()
               : getEndPoint();
    }
    public double getLength()
    {
        Coordinate p1 = getStartPoint();
        Coordinate p2 = getEndPoint();
        return DgnUtility.getLength(p1.x, p1.y, p2.x, p2.y);
    }
    public Coordinate pointAtDistance(double dDistance, double dTolerance)
    {
        return null;
    }
    public Coordinate[] getVertices()
    {
        Coordinate[] result = new Coordinate[2];
        result[0] = getStartPoint();
        result[1] = getEndPoint();
        return result;
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        return factory.createLineString(getVertices());
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.LINE);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new LineElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineStringElement.java
New file
@@ -0,0 +1,171 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.util.DgnUtility;
/**
 * LineStringElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 02:48:58
 */
public class LineStringElement extends Element implements GeometryConverter
{
    private static final Logger logger = Logger.getLogger(LineStringElement.class);
    public LineStringElement(byte[] raw)
    {
        super(raw);
    }
    public Coordinate getCentroid(double dTolerance)
    {
        return null;
    }
    public Coordinate getEndPoint()
    {
        return new Coordinate(getX(getVerticeSize() - 1), getY(getVerticeSize() - 1));
    }
    public Coordinate getNormal()
    {
        return null;
    }
    public Coordinate getOrigin()
    {
        return null;
    }
    public Coordinate getStartPoint()
    {
        return new Coordinate(getX(0), getY(0));
    }
    public Coordinate getVertex(int index)
    {
        return (index == 0)
               ? getStartPoint()
               : getEndPoint();
    }
    public int getVerticeSize()
    {
        return raw[18] & 0x0000ffff;
    }
    public double getLength()
    {
        double       result = 0.0;
        Coordinate[] vset   = getVertices();
        for (int i = 1; i < getVerticeSize(); i++)
        {
            Coordinate p1 = vset[i - 1];
            Coordinate p2 = vset[i];
            result += DgnUtility.getLength(p1.x, p1.y, p2.x, p2.y);
        }
        return result;
    }
    public Coordinate pointAtDistance(double dDistance, double dTolerance)
    {
        return null;
    }
    public Coordinate[] getVertices()
    {
        Coordinate[] result = new Coordinate[getVerticeSize()];
        for (int i = 0; i < getVerticeSize(); i++)
        {
            result[i] = new Coordinate(getX(i), getY(i));
        }
        return result;
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        return factory.createLineString(getVertices());
    }
    protected double getX(int index)
    {
        if ((index < 0) || (index > getVerticeSize()))
        {
            return -1;
        }
        int x = ((raw[19 + (4 * index)] << 16) & 0xffff0000);
        x += (raw[20 + (4 * index)] & 0x0000ffff);
        return DgnUtility.converUnitToCoord(x);
    }
    protected void setX(int index, double dx)
    {
        int newVal = DgnUtility.converCoordToUnit(dx);
        raw[19 + (4 * index)] = (short) (newVal >> 16 & 0x0000ffff);
        raw[20 + (4 * index)] = (short) (newVal & 0x0000ffff);
    }
    protected double getY(int index)
    {
        if ((index < 0) || (index > getVerticeSize()))
        {
            return -1;
        }
        int y = ((raw[21 + (4 * index)] << 16) & 0xffff0000);
        y = y + (raw[22 + (4 * index)] & 0x0000ffff);
        return DgnUtility.converUnitToCoord(y);
    }
    protected void setY(int index, double dy)
    {
        int newVal = DgnUtility.converCoordToUnit(dy);
        raw[21 + (4 * index)] = (short) ((newVal >> 16) & 0x0000ffff);
        raw[22 + (4 * index)] = (short) (newVal & 0x0000ffff);
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.LINESTRING);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new LineStringElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/Lock.java
New file
@@ -0,0 +1,263 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
/**
 * Lock
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤W¤È 10:27:24
 */
public class Lock
{
    Logger logger = LogManager.getLogger("com.ximple.io.dgn7");
    /**
     * indicates a write is occurring
     */
    int writeLocks = 0;
    /**
     * if not null a writer is waiting for the lock or is writing.
     */
    Thread writer;
    /**
     * Thread->Owner map. If empty no read locks exist.
     */
    Map owners = new HashMap();
    /**
     * If the lock can be read locked the lock will be read and default
     * visibility for tests
     *
     * @return
     * @throws java.io.IOException
     */
    synchronized boolean canRead() throws IOException
    {
        if ((writer != null) && (writer != Thread.currentThread()))
        {
            return false;
        }
        if (writer == null)
        {
            return true;
        }
        if (owners.size() > 1)
        {
            return false;
        }
        return true;
    }
    /**
     * If the lock can be read locked the lock will be read and default
     * visibility for tests
     *
     * @return
     * @throws IOException
     */
    synchronized boolean canWrite() throws IOException
    {
        if (owners.size() > 1)
        {
            return false;
        }
        if ((canRead()) && ((writer == Thread.currentThread()) || (writer == null)))
        {
            if (owners.isEmpty())
            {
                return true;
            }
            if (owners.containsKey(Thread.currentThread()))
            {
                return true;
            }
        }
        return false;
    }
    /**
     * Called by shapefileReader before a read is started and before an IOStream
     * is openned.
     *
     * @throws IOException
     */
    public synchronized void lockRead() throws IOException
    {
        if (!canRead())
        {
            while ((writeLocks > 0) || (writer != null))
            {
                try
                {
                    wait();
                } catch (InterruptedException e)
                {
                    throw(IOException) new IOException().initCause(e);
                }
            }
        }
        assertTrue("A write lock exists that is owned by another thread", canRead());
        Thread current = Thread.currentThread();
        Owner  owner   = (Owner) owners.get(current);
        if (owner != null)
        {
            owner.timesLocked++;
        } else
        {
            owner = new Owner(current);
            owners.put(current, owner);
        }
        logger.debug("Start Read Lock:" + owner);
    }
    private void assertTrue(String message, boolean b)
    {
        if (!b)
        {
            throw new AssertionError(message);
        }
    }
    /**
     * Called by ShapefileReader after a read is complete and after the IOStream
     * is closed.
     */
    public synchronized void unlockRead()
    {
        assertTrue("Current thread does not have a readLock", owners.containsKey(Thread.currentThread()));
        Owner owner = (Owner) owners.get(Thread.currentThread());
        assertTrue("Current thread has " + owner.timesLocked + "negative number of locks", owner.timesLocked > 0);
        owner.timesLocked--;
        if (owner.timesLocked == 0)
        {
            owners.remove(Thread.currentThread());
        }
        notifyAll();
        logger.debug("unlock Read:" + owner);
    }
    /**
     * Called by ShapefileDataStore before a write is started and before an
     * IOStream is openned.
     *
     * @throws IOException
     */
    public synchronized void lockWrite() throws IOException
    {
        Thread currentThread = Thread.currentThread();
        if (writer == null)
        {
            writer = currentThread;
        }
        while (!canWrite())
        {
            try
            {
                wait();
            } catch (InterruptedException e)
            {
                throw(IOException) new IOException().initCause(e);
            }
            if (writer == null)
            {
                writer = currentThread;
            }
        }
        if (writer == null)
        {
            writer = currentThread;
        }
        assertTrue("The current thread is not the writer", writer == currentThread);
        assertTrue("There are read locks not belonging to the current thread.", canRead());
        writeLocks++;
        logger.debug(currentThread.getName() + " is getting write lock:" + writeLocks);
    }
    /**
     * default visibility for tests
     */
    synchronized int getReadLocks(Thread thread)
    {
        Owner owner = (Owner) owners.get(thread);
        if (owner == null)
        {
            return -1;
        }
        return owner.timesLocked;
    }
    public synchronized void unlockWrite()
    {
        if (writeLocks > 0)
        {
            assertTrue("current thread does not own the write lock", writer == Thread.currentThread());
            assertTrue("writeLock has already been unlocked", writeLocks > 0);
            writeLocks--;
            if (writeLocks == 0)
            {
                writer = null;
            }
        }
        logger.debug("unlock write:" + Thread.currentThread().getName());
        notifyAll();
    }
    /**
     * default visibility for tests
     */
    synchronized boolean ownWriteLock(Thread thread)
    {
        return (writer == thread) && (writeLocks > 0);
    }
    private class Owner
    {
        final Thread owner;
        int          timesLocked;
        Owner(Thread owner)
        {
            this.owner  = owner;
            timesLocked = 1;
        }
        public String toString()
        {
            return owner.getName() + " has " + timesLocked + " locks";
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/NIOUtilities.java
New file
@@ -0,0 +1,114 @@
package com.ximple.io.dgn7;
/*
 *    GeoTools - OpenSource mapping toolkit
 *    http://geotools.org
 *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
 *
 *    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.
 */
// J2SE dependencies
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * Utility class for managing memory mapped buffers.
 *
 * @since 2.0
 * @source $URL$
 * @version $Id$
 * @author Andres Aimes
 */
public class NIOUtilities {
    /**
     * {@code true} if a warning has already been logged.
     */
    private static boolean warned = false;
    /**
     * Do not allows instantiation of this class.
     *
     * @todo This constructor will become private when {@code NIOBufferUtils}
     *       will have been removed.
     */
    protected NIOUtilities() {
    }
    /**
     * Really closes a {@code MappedByteBuffer} without the need to wait for garbage
     * collection. Any problems with closing a buffer on Windows (the problem child in this
     * case) will be logged as {@code SEVERE} to the logger of the package name. To
     * force logging of errors, set the System property "org.geotools.io.debugBuffer" to "true".
     *
     * @param  buffer The buffer to close.
     * @return true if the operation was successful, false otherwise.
     *
     * @see java.nio.MappedByteBuffer
     */
    public static boolean clean(final ByteBuffer buffer) {
        if (buffer == null || ! buffer.isDirect() ) {
            return false;
        }
        Boolean b = (Boolean) AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                Boolean success = Boolean.FALSE;
                try {
                    Method getCleanerMethod = buffer.getClass().getMethod("cleaner", (Class[])null);
                    getCleanerMethod.setAccessible(true);
                    Object cleaner = getCleanerMethod.invoke(buffer,  (Object[])null);
                    Method clean = cleaner.getClass().getMethod("clean", (Class[])null);
                    clean.invoke(cleaner, (Object[])null);
                    success = Boolean.TRUE;
                } catch (Exception e) {
                    // This really is a show stopper on windows
                    if (isLoggable()) {
                        log(e, buffer);
                    }
                }
                return success;
            }
        });
        return b.booleanValue();
    }
    /**
     * Check if a warning message should be logged.
     */
    private static synchronized boolean isLoggable() {
        try {
            return !warned && (
                    System.getProperty("org.geotools.io.debugBuffer", "false").equalsIgnoreCase("true") ||
                    System.getProperty("os.name").indexOf("Windows") >= 0 );
        } catch (SecurityException exception) {
            // The utilities may be running in an Applet, in which case we
            // can't read properties. Assumes we are not in debugging mode.
            return false;
        }
    }
    /**
     * Log a warning message.
     */
    private static synchronized void log(final Exception e, final ByteBuffer buffer) {
        warned = true;
        String message = "Error attempting to close a mapped byte buffer : " + buffer.getClass().getName()
                       + "\n JVM : " + System.getProperty("java.version")
                       + ' '         + System.getProperty("java.vendor");
        Logger.getLogger("org.geotools.io").log(Level.SEVERE, message, e);
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ShapeElement.java
New file
@@ -0,0 +1,62 @@
package com.ximple.io.dgn7;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
/**
 * ShapeElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 03:08:43
 */
public class ShapeElement extends LineStringElement implements GeometryConverter
{
    private static final Logger logger = Logger.getLogger(ShapeElement.class);
    public ShapeElement(byte[] raw)
    {
        super(raw);
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        try
        {
            LinearRing ring = factory.createLinearRing(this.getVertices());
            return factory.createPolygon(ring, null);
        } catch (IllegalArgumentException e)
        {
            logger.warn(e.getMessage(), e);
            return null;
        }
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.SHAPE);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new ShapeElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/StreamLogging.java
New file
@@ -0,0 +1,45 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
/**
 * StreamLogging
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤W¤È 10:31:08
 */
public class StreamLogging
{
    private static final Logger LOGGER = LogManager.getLogger("com.ximple.io.dgn7");
    private String              name;
    private int                 open = 0;
    /**
     * The name that will appear in the debug message
     *
     * @param name
     */
    public StreamLogging(String name)
    {
        this.name = name;
    }
    /**
     * Call when reader or writer is opened
     */
    public synchronized void open()
    {
        open++;
        LOGGER.debug(name + " has been opened. Number open: " + open);
    }
    public synchronized void close()
    {
        open--;
        LOGGER.debug(name + " has been closed. Number open: " + open);
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TcbElement.java
New file
@@ -0,0 +1,94 @@
package com.ximple.io.dgn7;
import org.apache.log4j.Logger;
/**
 * TcbElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 05:03:46
 */
public class TcbElement extends Element
{
    private static final Logger logger = Logger.getLogger(TcbElement.class);
    public TcbElement(byte[] raw)
    {
        super(raw);
    }
    public boolean is2D()
    {
        int dimension = (int) (raw[607] & 0x00000004);
        if (dimension == 0)
        {
            return true;
        } else
        {
            return false;
        }
    }
    public String getMasterUnitName()
    {
        byte[] master = new byte[1];
        master[0] = (byte) (raw[560] & 0x00ff);
        java.nio.charset.Charset.forName("US-ASCII");
        // ASCIIEncoding encode = new ASCIIEncoding();
        StringBuffer sb = new StringBuffer();
        sb.append((char) master[0]);
        // return encode.GetString(master);
        return sb.toString();
    }
    public String getSubUnitName()
    {
        byte[] sub = new byte[2];
        sub[0] = (byte) (raw[561] & 0x00ff);
        sub[1] = (byte) (raw[561] >> 8 & 0x00ff);
        StringBuffer sb = new StringBuffer();
        sb.append((char) sub[0]);
        sb.append((char) sub[0]);
        return sb.toString();
    }
    public int getGraphicGroup()
    {
        return (int) (raw[594] & 0x0000ffff);
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.TCB);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new TcbElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java
New file
@@ -0,0 +1,340 @@
package com.ximple.io.dgn7;
import java.awt.geom.AffineTransform;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.util.DgnUtility;
/**
 * TextElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤W¤È 11:45:29
 */
public class TextElement extends Element implements GeometryConverter
{
    private static final Logger logger = Logger.getLogger(TextElement.class);
    public static final int ED_CENTERJUSTIFICATION = 0;
    //  Enter data field center justification
    public static final int ED_LEFTJUSTIFICATION = 0;
    //  Enter data field left justification
    public static final int ED_RIGHTJUSTIFICATION = 0;
    public static final int TXTJUST_LT = 0;    /* Left Top */
    public static final int TXTJUST_LC = 1;    /* Left Center */
    public static final int TXTJUST_LB = 2;    /* Left Bottom */
    public static final int TXTJUST_LMT = 3;   /* Left Margin Top */
    public static final int TXTJUST_LMC = 4;   /* Left Margin Center */
    public static final int TXTJUST_LMB = 5;   /* Left Margin Bottom */
    public static final int TXTJUST_CT = 6;    /* Center Top */
    public static final int TXTJUST_CC = 7;    /* Center Center */
    public static final int TXTJUST_CB = 8;    /* Center Bottom */
    public static final int TXTJUST_RMT = 9;   /* Right Margin Top */
    public static final int TXTJUST_RMC = 10;  /* Right Margin Center */
    public static final int TXTJUST_RMB = 11;  /* Right Margin Bottom */
    public static final int TXTJUST_RT = 12;   /* Right Top */
    public static final int TXTJUST_RC = 13;   /* Right Center */
    public static final int TXTJUST_RB = 14;   /* Right Bottom */
    public static final int TXTJUST_LU = 15;   /* Left Cap */
    public static final int TXTJUST_LD = 16;   /* Left Descender */
    public static final int TXTJUST_LMU = 17;  /* Left Margin Cap */
    public static final int TXTJUST_LMD = 18;  /* Left Margin Descender */
    public static final int TXTJUST_CU = 19;   /* Center Cap */
    public static final int TXTJUST_CD = 20;   /* Center Descender */
    public static final int TXTJUST_RMU = 21;  /* Right Margin Cap */
    public static final int TXTJUST_RMD = 22;  /* Right Margin Descender */
    public static final int TXTJUST_RU = 23;   /* Right Cap */
    public static final int TXTJUST_RD = 24;   /* Right Descender */
    public static final int TXTJUST_NONE = 127;/* no justfication */
    public TextElement(byte[] raw)
    {
        super(raw);
    }
    public Coordinate getOrigin()
    {
        int x = (raw[25] << 16 & 0xffff0000);
        x += raw[26] & 0x0000ffff;
        double dx = DgnUtility.converUnitToCoord(x);
        int y = (raw[27] << 16 & 0xffff0000);
        y += raw[28] & 0x0000ffff;
        double dy = DgnUtility.converUnitToCoord(y);
        return new Coordinate(dx, dy);
    }
    public int getFontIndex()
    {
        return (int) raw[18] & 0x00000000ff;
    }
    public boolean hasSlant()
    {
        return true;
    }
    public boolean hasUnderline()
    {
        return true;
    }
    public boolean isFixedWidthSpacing()
    {
        return true;
    }
    public boolean isPlanar()
    {
        return true;
    }
    public boolean isVertical()
    {
        return true;
    }
    public double getTextHeight()
    {
        int height = ((raw[21] << 16) & 0xffff0000);
        height += raw[22] & 0x0000ffff;
        return DgnUtility.converIntToDouble(height);
    }
    public double getTextWidth()
    {
        int length = (raw[19] << 16 & 0xffff0000);
        length += raw[20] & 0x0000ffff;
        return DgnUtility.converIntToDouble(length);
    }
    public int getJustification()
    {
        return ((raw[18] >>> 8) & 0x00000000ff);
    }
    public double getRotationAngle()
    {
        int totation = ((raw[23] & 0x0000ffff) << 16) | (raw[24] & 0x0000ffff);
        return DgnUtility.converIntToRotation(totation);
    }
    public boolean isChinese()
    {
        int isChinese = raw[30] & 0x0000ffff;
        return (isChinese == 0xfdff);
    }
    public int getTextLength()
    {
        int num = raw[29];
        if (isChinese())
        {
            num = (num / 2) - 1;
        }
        return num;
    }
    public String getText()
    {
        StringBuffer val = new StringBuffer();
        char[] temp;
        int num = getTextLength();
        if (!isChinese())
        {
            temp = new char[num];
            for (int i = 0; i < temp.length; i++)
            {
                if ((i % 2) == 0)
                {
                    temp[i] = (char) (raw[30 + (int) (i / 2)] & (short) 0x00ff);
                } else
                {
                    temp[i] = (char) ((raw[30 + (int) (i / 2)] >> 8) & (short) 0x00ff);
                }
                val.append(temp[i]);
            }
        } else
        {
            byte[] strRaw = new byte[num * 2];
            for (int i = 0; i < num; i++)
            {
                short charValue = raw[i + 31];
                byte hi = (byte) (charValue >>> 8);
                byte lo = (byte) charValue;
                strRaw[i * 2] = hi;
                strRaw[i * 2 + 1] = lo;
            }
            try
            {
                Charset charsetBig5 = Charset.forName("Big5");
                CharsetDecoder decoder = charsetBig5.newDecoder();
                CharBuffer cb = decoder.decode(ByteBuffer.wrap(strRaw));
                val.append(cb);
            } catch (CharacterCodingException e)
            {
                logger.warn(e.getMessage(), e);
                return val.toString();
            } finally
            {
                // rawBuffer.position(pos);
                // rawBuffer.order(order);
            }
        }
        return val.toString();
    }
    protected byte[] convertDBCSToUnicode(byte[] buffer)
    {
        byte[] charBuffer = new byte[4];
        charBuffer[0] = (byte) ((byte) ((buffer[1] & 0xc0) >>> 6) | 0xc0);
        charBuffer[1] = (byte) (buffer[1] & 0x3f | 0x80);
        charBuffer[2] = (byte) ((byte) ((buffer[0] & 0xc0) >>> 6) | 0xc0);
        charBuffer[3] = (byte) (buffer[0] & 0x3f | 0x80);
        return charBuffer;
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        return factory.createPoint(getUserOrigin());
    }
    private double getUserWidth()
    {
        int just = getJustification();
        // Envelope range = getRange();         // case -1
        // double width = (range.getWidth());   // case -1
        // double width = this.getTextWidth() * this.getTextLength() * 1000.0; // case -2
        double width = (this.getTextWidth() * this.getTextLength());
        switch (just)
        {
        case TXTJUST_LT:
        case TXTJUST_LC:
        case TXTJUST_LB:
            width = 0;
            break;
        case TXTJUST_CT:
        case TXTJUST_CC:
        case TXTJUST_CB:
            width = width / 2;
            break;
        case TXTJUST_RT:
        case TXTJUST_RC:
        case TXTJUST_RB:
            break;
        }
        return width;
    }
    private double getUserHeight()
    {
        int just = getJustification();
        double height = getTextHeight();
        switch (just)
        {
        case TXTJUST_LB:
        case TXTJUST_CB:
        case TXTJUST_RB:    // bottom
            height = 0;
            break;
        case TXTJUST_LC:
        case TXTJUST_CC:
        case TXTJUST_RC:    // center
            height = height / 2;
            break;
        case TXTJUST_LT:
        case TXTJUST_CT:
        case TXTJUST_RT:    // height
            break;
        }
        return height;
    }
    public Coordinate getUserOrigin()
    {
        double width = getUserWidth();
        double height = getUserHeight();
        double angle = Math.toRadians(getRotationAngle());
        AffineTransform at = new AffineTransform();
        at.translate(width, height);
        Coordinate p = getOrigin();
        at.setToRotation(angle, p.x, p.y);
        at.scale(1, 1);
        double[] srcPt = new double[2];
        double[] dstPt = new double[2];
        srcPt[0] = p.x + width;
        srcPt[1] = p.y + height;
        at.transform(srcPt, 0, dstPt, 0, 1);
        return new Coordinate(dstPt[0], dstPt[1]);
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.TEXT);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new TextElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java
New file
@@ -0,0 +1,289 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.util.DgnUtility;
/**
 * TextNodeElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 04:02:58
 */
public class TextNodeElement extends Element implements ComplexElement, GeometryConverter
{
    private static final Logger logger = Logger.getLogger(TextElement.class);
    private ArrayList list = new ArrayList();
    public TextNodeElement(byte[] raw)
    {
        super(raw);
    }
    public int size()
    {
        return list.size();
    }
    public boolean isEmpty()
    {
        return list.isEmpty();
    }
    public boolean contains(Object o)
    {
        return list.contains(o);
    }
    public Iterator iterator()
    {
        return list.iterator();
    }
    public Object[] toArray()
    {
        return list.toArray();
    }
    public boolean add(Object o)
    {
        return list.add(o);
    }
    public boolean remove(Object o)
    {
        return list.remove(o);
    }
    public boolean addAll(Collection c)
    {
        return list.addAll(c);
    }
    public boolean addAll(int index, Collection c)
    {
        return list.addAll(index, c);
    }
    public void clear()
    {
        list.clear();
    }
    public Object get(int index)
    {
        return list.get(index);
    }
    public Object set(int index, Object element)
    {
        return list.set(index, element);
    }
    public void add(int index, Object element)
    {
        list.add(index, element);
    }
    public Object remove(int index)
    {
        return list.remove(index);
    }
    public int indexOf(Object o)
    {
        return list.indexOf(o);
    }
    public int lastIndexOf(Object o)
    {
        return list.lastIndexOf(o);
    }
    public ListIterator listIterator()
    {
        return list.listIterator();
    }
    public ListIterator listIterator(int index)
    {
        return list.listIterator(index);
    }
    public List subList(int fromIndex, int toIndex)
    {
        return list.subList(fromIndex, toIndex);
    }
    public boolean retainAll(Collection c)
    {
        return list.retainAll(c);
    }
    public boolean removeAll(Collection c)
    {
        return list.removeAll(c);
    }
    public boolean containsAll(Collection c)
    {
        return list.containsAll(c);
    }
    public Object[] toArray(Object[] a)
    {
        return list.toArray(a);
    }
    public String[] getTextArray()
    {
        ArrayList list = new ArrayList();
        for (ListIterator it = listIterator(); it.hasNext(); )
        {
            Element element = (Element) it.next();
            if (element instanceof TextElement)
            {
                list.add(((TextElement) element).getText());
            }
        }
        return (String[]) list.toArray(new String[list.size()]);
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        /*
         * CoordinateList coords = new CoordinateList();
         * for (ListIterator it = listIterator(); it.hasNext(); )
         * {
         *   Element element = (Element) it.next();
         *   if (element instanceof TextElement)
         *   {
         *       coords.add(((TextElement) element).getUserOrigin());
         *   }
         * }
         */
        return factory.createPoint(getOrigin());
        // return factory.createMultiPoint(coords.toCoordinateArray());
    }
    public int getNumString()
    {
        return (raw[19] & 0x0000ffff);
    }
    public int getNodeNumber()
    {
        return (raw[20] & 0x0000ffff);
    }
    public int getMaxLength()
    {
        return (raw[21] & 0x00ff);
    }
    public int getMaxUsed()
    {
        return ((raw[21] >> 8) & 0x00ff);
    }
    public int getJustification()
    {
        return ((raw[22] >> 8) & 0x00ff);
    }
    public int getFontIndex()
    {
        return (raw[22] & 0x00ff);
    }
    public double getLineSpacing()
    {
        int lineSpace;
        lineSpace = ((raw[23] & 0x0000ffff) << 16) | (raw[24] & 0x0000ffff);
        return lineSpace;
    }
    public double getTextNodeLength()
    {
        int lengthMult;
        lengthMult = ((raw[25] << 16) & 0xffff0000);
        lengthMult += (raw[26] & 0x0000ffff);
        return DgnUtility.converIntToDouble(lengthMult);
    }
    public double getTextNodeHeight()
    {
        int heightMult;
        heightMult = ((raw[27] << 16) & 0xffff0000);
        heightMult += (raw[28] & 0x0000ffff);
        return DgnUtility.converIntToDouble(heightMult);
    }
    public double getRotationAngle()
    {
        int rotation = (raw[29] << 16 & 0xffff0000);
        rotation += raw[30];
        return DgnUtility.converIntToRotation(rotation);
    }
    public Coordinate getOrigin()
    {
        int x = ((raw[31] << 16) & 0xffff0000) | (raw[32] & 0x0000ffff);
        double dx = DgnUtility.converUnitToCoord(x);
        // return DgnUtility.convertFromDGN(x);
        int y  = ((raw[33] << 16) & 0xffff0000) | (raw[34] & 0x0000ffff);
        double dy = DgnUtility.converUnitToCoord(y);
        return new Coordinate(dx, dy);
    }
    public static class ElementHandler extends Element.ElementHandler
    {
        private static ElementHandler instance = null;
        public ElementHandler()
        {
            super(ElementType.TEXTNODE);
        }
        public static IElementHandler getInstance()
        {
            if (instance == null)
            {
                instance = new ElementHandler();
            }
            return instance;
        }
        protected Element createElement(byte[] raw)
        {
            return new TextNodeElement(raw);
        }
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/UserAttributeData.java
New file
@@ -0,0 +1,34 @@
package com.ximple.io.dgn7;
/**
 * UserAttributeData
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 02:29:29
 */
public class UserAttributeData
{
    protected short[] _src;
    public UserAttributeData(short id, int attributeCount)
    {
        _src    = new short[attributeCount];
        _src[0] = id;
    }
    public UserAttributeData(short[] src)
    {
        _src = src;
    }
    public short getID()
    {
        return _src[0];
    }
    public void setID(short value)
    {
        _src[0] = value;
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/util/DgnUtility.java
New file
@@ -0,0 +1,259 @@
package com.ximple.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.Envelope;
/**
 * Utility
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 01:33:00
 */
public final class DgnUtility
{
    private static final Logger logger = Logger.getLogger(DgnUtility.class);
    public static double converIntToDouble(int src)
    {
        return (double) ((long) ((src * 6) / 1000.0 + 0.5)) / 1000.0;
    }
    public static int converDoubleToInt(double src)
    {
        return (int) (src / 6 * 1000000.0);
    }
    public static int convertFromDGN(int aValue)
    {
        int newVal;
        newVal = (((aValue ^ 0x00008000) << 16) & 0xffff0000);
        newVal |= (aValue >>> 16) & 0x0000ffff;
        return newVal;
    }
    public static int converToDGN(int aValue)
    {
        int newVal;
        newVal = (aValue << 16 & 0xffff0000);
        newVal |= (((aValue ^ 0x80000000) >>> 16) & 0x0000ffff);
        return newVal;
    }
    public static double converIntToRotation(int aValue)
    {
        return aValue / 360000.0;
    }
    public static int converRotatioToInt(double aValue)
    {
        return (int) (aValue * 360000.0);
    }
    public static double converRotationToRadian(double aValue)
    {
        return aValue * Math.PI / 180;
    }
    public static double converUnitToCoord(int aValue)
    {
        double newVal;
        newVal = aValue / 1000.0;
        newVal += 2147483.648;    // 2147483.648 = 2 ^ 31
        return newVal;
    }
    public static double converUnitToCoord(double aValue)
    {
        double newVal;
        newVal = aValue / 1000.0;
        newVal += 2147483.648;    // 2147483.648 = 2 ^ 31
        return newVal;
    }
    public static int converCoordToUnit(double aValue)
    {
        double newVal = aValue;
        newVal -= 2147483.648;
        newVal = newVal * 1000.0;
        return (int) newVal;
    }
    public static Envelope converUnitToCoord(Envelope range)
    {
        if (range == null)
        {
            return null;
        }
        return new Envelope(converUnitToCoord((int) range.getMinX()), converUnitToCoord((int) range.getMaxX()),
                                         converUnitToCoord((int) range.getMinY()), converUnitToCoord((int) range.getMaxY()));
    }
    public static Envelope converCoordToUnit(Envelope range)
    {
        if (range == null)
        {
            return null;
        }
        return new Envelope(converCoordToUnit(range.getMinX()), converCoordToUnit(range.getMaxX()),
                                         converCoordToUnit(range.getMinY()), converCoordToUnit(range.getMaxY()));
    }
    public static long convertDGNToRAWIEEEDouble(byte[] org)
    {
        ByteBuffer buf = ByteBuffer.allocate(8);
        buf.order(ByteOrder.LITTLE_ENDIAN);
        buf.mark();
        buf.put(org[2]);
        buf.put(org[3]);
        buf.put(org[0]);
        buf.put(org[1]);
        buf.put(org[6]);
        buf.put(org[7]);
        buf.put(org[4]);
        buf.put(org[5]);
        buf.position(0);
        int[] tmp = new int[2];
        tmp[0]   = buf.getInt();
        tmp[1]   = buf.getInt();
        int   exponent;
        int sign     = (tmp[0] & 0x80000000);
        exponent = (tmp[0] >>> 23) & 0x000000ff;
        if (exponent != 0)
        {
            exponent = exponent - 129 + 1023;
        }
        int rndbits = tmp[1] & 0x00000007;
        tmp[1]  = tmp[1] >>> 3;
        tmp[1]  = (tmp[1] & 0x1fffffff) | (tmp[0] << 29);
        if (rndbits != 0)
        {
            tmp[1] = tmp[1] | 0x00000001;
        }
        tmp[0] = (tmp[0] >>> 3) & 0x000fffff;
        tmp[0] = tmp[0] | (exponent << 20) | sign;
        buf.position(0);
        buf.order(ByteOrder.BIG_ENDIAN);
        buf.putInt(tmp[0]);
        buf.putInt(tmp[1]);
        buf.position(0);
        byte[] tmpRaw = new byte[8];
        buf.get(tmpRaw);
        buf.position(0);
        buf.order(ByteOrder.LITTLE_ENDIAN);
        for (int i = tmpRaw.length; i > 0 ; i--)
        {
            buf.put(tmpRaw[i-1]);
        }
        buf.position(0);
        long result = buf.getLong();
        return result;
    }
    public static double convertDGNToIEEEDouble(byte[] src)
    {
        return Double.longBitsToDouble(convertDGNToRAWIEEEDouble(src));
    }
    public static short[] convertIEEEDoubleToDGN(double src)
    {
        long newVal = Double.doubleToLongBits(src);
        // uint[]   tmp = new int[ 2 ];
        // ushort[] des = new short[ 4 ];
        int[]   tmp = new int[2];
        short[] des = new short[4];
        int     sign;
        int     exponent;
        tmp[0] = (int) ((newVal >>> 32));
        tmp[1] = (int) (newVal);
        // sign = ( int ) ( ( uint ) tmp[ 0 ] & 0x80000000 );
        sign     = tmp[0] & 0x80000000;
        exponent = (tmp[0] >>> 20) & 0x07ff;
        if (exponent != 0)
        {
            exponent = exponent - 1023 + 129;
        }
        if (exponent > 255)
        {
            if (sign != 0)
            {
                des[0] = -1;
            } else
            {
                des[0] = 0x7fff;
            }
            des[1] = -1;
            des[2] = -1;
            des[3] = -1;
            return des;
        } else if ((exponent < 0) || ((exponent == 0) && (sign == 0)))
        {
            des[0] = 0x0;
            des[1] = 0x0;
            des[2] = 0x0;
            des[3] = 0x0;
            return des;
        } else
        {
            tmp[0] = (tmp[0] << 3) | (tmp[1] >> 29);
            tmp[0] = tmp[0] & 0x007fffff;
            tmp[0] = tmp[0] | (exponent << 23) | sign;
            // changed by phil 07/05/2004
            // tmp[ 1 ] = tmp[ 1 ] >> 3;
            tmp[1] = tmp[1] << 3;
        }
        des[0] = (short) ((tmp[0] >>> 16) & 0x0000ffff);
        des[1] = (short) (tmp[0] & 0x0000ffff);
        des[2] = (short) ((tmp[1] >>> 16) & 0x0000ffff);
        des[3] = (short) (tmp[1] & 0x0000ffff);
        return des;
    }
    public static double getLength(double x1, double y1, double x2, double y2)
    {
        double dx     = x1 - x2;
        double dy     = y1 - y2;
        return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
    }
}
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/util/PrintfFormat.java
New file
Diff too large
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7OracleReaderTest.java
New file
@@ -0,0 +1,125 @@
package com.ximple.io.dgn7;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.vividsolutions.jts.geom.Coordinate;
import com.ximple.util.PrintfFormat;
import oracle.jdbc.OracleConnection;
/**
 * Dgn7OracleReaderTest
 * User: Ulysses
 * Date: 2007/10/24
 * Time: ¤W¤È 10:49:54
 */
public class Dgn7OracleReaderTest
{
    @BeforeTest
    public void setUp()
    {
    }
    @Test
    public void testOracleReader() throws SQLException, IOException
    {
        OracleConnection connection = OracleTarget.getInstance().getOracleConnection();
        // String fetchSrcStmtFmt = "SELECT IGDSELM FROM \"%s\".\"%s\" ORDER BY ROWID";
        String fetchSrcStmtFmt = "SELECT IGDSELM FROM \"%s\".\"%s\" WHERE TAG_SFSC=106 ORDER BY ROWID";
        PrintfFormat spf = new PrintfFormat(fetchSrcStmtFmt);
        String srcschema = "SPATIALDB";
        String srctable = "IGSET_1";
        String fetchSrcStmt = spf.sprintf(new Object[]{srcschema, srctable});
        Dgn7OracleReader reader = new Dgn7OracleReader(fetchSrcStmt, "IGDSELM", connection);
        int count = 0;
        while (reader.hasNext())
        {
            Element element = reader.next();
            if (element instanceof ComplexChainElement)
            {
                ComplexChainElement complexChain = (ComplexChainElement) element;
                FrammeAttributeData frammeLinkage = null;
                List<UserAttributeData> attrs = complexChain.getUserAttributeData();
                for (int k = 0; k < attrs.size(); k++)
                {
                    UserAttributeData userAttr = attrs.get(k);
                    if (userAttr instanceof FrammeAttributeData)
                    {
                        frammeLinkage = (FrammeAttributeData) userAttr;
                        break;
                    }
                }
                System.out.print("complexChain:");
                if (frammeLinkage != null)
                    System.out.print(":FSC-" + frammeLinkage.getFsc() +
                                       ":UFID-" + frammeLinkage.getUfid() +
                                       ":COMP-" + frammeLinkage.getComponentID());
                else
                    System.out.print("Linkage is null");
                for (int i = 0; i < complexChain.size(); i++)
                {
                    Element elm = (Element) complexChain.get(i);
                    if (elm instanceof LineStringElement)
                    {
                        LineStringElement lineStringElement = (LineStringElement) elm;
                        int size = lineStringElement.getVerticeSize();
                        System.out.print("size=" + size + ":");
                        Coordinate[] coords = lineStringElement.getVertices();
                        for (int j = 0; j < coords.length; j++)
                            System.out.print("[" + j + "]" + coords[j].toString());
                    }
                }
                System.out.println();
            } else if (element instanceof TextNodeElement)
            {
                TextNodeElement textNode = (TextNodeElement) element;
                FrammeAttributeData frammeLinkage = null;
                List<UserAttributeData> attrs = textNode.getUserAttributeData();
                for (int k = 0; k < attrs.size(); k++)
                {
                    UserAttributeData userAttr = attrs.get(k);
                    if (userAttr instanceof FrammeAttributeData)
                    {
                        frammeLinkage = (FrammeAttributeData) userAttr;
                        break;
                    }
                }
                Coordinate coord = textNode.getOrigin();
                System.out.print("TextNode:origin=" + coord.toString());
                if (frammeLinkage != null)
                    System.out.print(":FSC-" + frammeLinkage.getFsc() +
                                       ":UFID-" + frammeLinkage.getUfid() +
                                       ":COMP-" + frammeLinkage.getComponentID());
                else
                    System.out.print("Linkage is null");
                for (int i = 0; i < textNode.size(); i++)
                {
                    Element elm = (Element) textNode.get(i);
                    if (elm instanceof TextElement)
                    {
                        TextElement textElm = (TextElement) elm;
                        System.out.print("---");
                        String text = textElm.getText();
                        System.out.print("'" + text + "'");
                    }
                }
                System.out.println();
            }
        }
    }
}
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7TextElementReaderTest.java
New file
@@ -0,0 +1,180 @@
package com.ximple.io.dgn7;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import org.geotools.TestData;
/**
 * Dgn7TextElementReaderTest
 * User: Ulysses
 * Date: 2008/1/10
 * Time: ¤W¤È 12:19:14
 */
public class Dgn7TextElementReaderTest
{
    private final static Logger logger = Logger.getLogger(Dgn7fileReaderTest.class);
    private final static String testFilePathCreated = "demo.dgn";
    private final static String testFilePathExist = "HV88491-1.dgn";
    private final static String testFilePathPostComplete = "HV88494_0.dgn";
    private FileInputStream _fs;
    @BeforeTest
    public void setUp() throws FileNotFoundException
    {
    }
    @Test
    public void testRead() throws Dgn7fileException, IOException
    {
        File dataFile = TestData.file(this, testFilePathCreated);
        if (dataFile.exists())
        {
            System.out.println("Output--" + testFilePathCreated);
            _fs = new FileInputStream(dataFile);
            FileChannel fc = _fs.getChannel();
            dumpElements(fc);
            fc.close();
            _fs.close();
        }
        dataFile = TestData.file(this, testFilePathExist);
        if (dataFile.exists())
        {
            System.out.println("Output--" + testFilePathExist);
            _fs = new FileInputStream(dataFile);
            FileChannel fc = _fs.getChannel();
            dumpElements(fc);
            fc.close();
            _fs.close();
        }
        dataFile = TestData.file(this, testFilePathPostComplete);
        if (dataFile.exists())
        {
            System.out.println("Output--" + testFilePathPostComplete);
            _fs = new FileInputStream(dataFile);
            FileChannel fc = _fs.getChannel();
            dumpElements(fc);
            fc.close();
            _fs.close();
        }
    }
    public void dumpElements(FileChannel fc) throws Dgn7fileException, IOException
    {
        Dgn7fileReader reader = new Dgn7fileReader(fc, new Lock());
        int count = 0;
        Element lastComplex = null;
        while (reader.hasNext())
        {
            Dgn7fileReader.Record record = reader.nextElement();
            if (record.element() != null)
            {
                Element element = (Element) record.element();
                ElementType type = element.getElementType();
                if ((!type.isComplexElement()) && (!element.isComponentElement()))
                {
                    if (lastComplex != null)
                    {
                        // @todo add process in here
                        lastComplex = null;
                    }
                    // @todo add process in here
                } else if (element.isComponentElement())
                {
                    if (lastComplex != null)
                    {
                        ((ComplexElement) lastComplex).add(element);
                    }
                } else if (type.isComplexElement())
                {
                    if (lastComplex == null)
                    {
                        lastComplex = element;
                    } else
                    {
                        // @todo add process in here
                        lastComplex = element;
                    }
                }
                if (element.getElementType().isComplexElement())
                {
                    if (element instanceof ComplexChainElement)
                    {
                        ComplexChainElement complexChain = (ComplexChainElement) element;
                        int size = complexChain.size();
                        for (Object aComplexChain : complexChain)
                        {
                            Element subElement = (Element) aComplexChain;
                            subElement.getType();
                        }
                    }
                    if (element instanceof ComplexShapeElement)
                    {
                        ComplexShapeElement complexShape = (ComplexShapeElement) element;
                    }
                    if (element instanceof TextNodeElement)
                    {
                        TextNodeElement textNode = (TextNodeElement) element;
                        int size = textNode.size();
                        for (int i = 0; i < size; i++)
                        {
                            Element subElement = (Element) textNode.get(i);
                            subElement.getElementType();
                        }
                    }
                } else
                {
                    boolean hasLinkage = false;
                    if (element instanceof TextElement)
                    {
                        TextElement textElm = (TextElement) element;
                        List<UserAttributeData> usrData = textElm.getUserAttributeData();
                        Iterator<UserAttributeData> it = usrData.iterator();
                        while (it.hasNext())
                        {
                            UserAttributeData attr = it.next();
                            if (attr instanceof FrammeAttributeData)
                            {
                                hasLinkage = true;
                                System.out.println("------------------------------------------");
                                System.out.println("FSC=" + ((FrammeAttributeData) attr).getFsc() + ":" +
                                        ((FrammeAttributeData) attr).getUfid());
                            }
                        }
                        if (hasLinkage)
                        {
                            System.out.println("Text.Font=" + textElm.getFontIndex());
                            System.out.println("Text.Just=" + textElm.getJustification());
                            System.out.println("usrData.len=" + usrData.size());
                            System.out.println("text=" + textElm.getText());
                            System.out.println("Origin=" + textElm.getOrigin());
                            System.out.println("UserOrigin=" + textElm.getUserOrigin());
                        }
                    }
                }
            }
            count++;
        }
        logger.info("ElementRecord Count=" + count);
    }
}
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/Dgn7fileReaderTest.java
New file
@@ -0,0 +1,119 @@
package com.ximple.io.dgn7;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.channels.FileChannel;
import org.apache.log4j.Logger;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import org.geotools.TestData;
/**
 * Dgn7fileReaderTest
 * User: Ulysses
 * Date: 2007/10/24
 * Time: ¤W¤È 01:43:41
 * To change this template use File | Settings | File Templates.
 */
public class Dgn7fileReaderTest
{
    private final static Logger logger = Logger.getLogger(Dgn7fileReaderTest.class);
    // private final static String testFilePath = "test-data\\testHV.dgn";
    private final static String testFilePath = "testHV.dgn";
    private FileInputStream _fs;
    @BeforeTest
    public void setUp() throws IOException
    {
        File dataFile = TestData.file(this, testFilePath);
        if (!dataFile.exists())
        {
            return;
        }
        _fs = new FileInputStream(dataFile);
    }
    @Test
    public void testRead() throws Dgn7fileException, IOException
    {
        if (_fs == null) return;
        FileChannel fc = _fs.getChannel();
        Dgn7fileReader reader = new Dgn7fileReader(fc, new Lock());
        int count = 0;
        Element lastComplex = null;
        while (reader.hasNext())
        {
            Dgn7fileReader.Record record = reader.nextElement();
            if (record.element() != null)
            {
                Element element = (Element) record.element();
                ElementType type = element.getElementType();
                if ((!type.isComplexElement()) && (!element.isComponentElement()))
                {
                    if (lastComplex != null)
                    {
                        // @todo add process in here
                        lastComplex = null;
                    }
                    // @todo add process in here
                } else if (element.isComponentElement())
                {
                    if (lastComplex != null)
                    {
                        ((ComplexElement) lastComplex).add(element);
                    }
                } else if (type.isComplexElement())
                {
                    if (lastComplex == null)
                    {
                        lastComplex = element;
                    } else
                    {
                        // @todo add process in here
                        lastComplex = element;
                    }
                }
                if (element.getElementType().isComplexElement())
                {
                    if (element instanceof ComplexChainElement)
                    {
                        ComplexChainElement complexChain = (ComplexChainElement) element;
                        int size = complexChain.size();
                        for (Object aComplexChain : complexChain)
                        {
                            Element subElement = (Element) aComplexChain;
                            subElement.getType();
                        }
                    }
                    if (element instanceof ComplexShapeElement)
                    {
                        ComplexShapeElement complexShape = (ComplexShapeElement) element;
                    }
                    if (element instanceof TextNodeElement)
                    {
                        TextNodeElement textNode = (TextNodeElement) element;
                        int size = textNode.size();
                        for (int i = 0; i < size; i++)
                        {
                            Element subElement = (Element) textNode.get(i);
                            subElement.getElementType();
                        }
                    }
                }
            }
            count++;
        }
        logger.info("ElementRecord Count=" + count);
    }
}
xdgnjobs/ximple-dgnio/src/test/java/com/ximple/io/dgn7/OracleTarget.java
New file
@@ -0,0 +1,162 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.util.Assert;
import oracle.jdbc.OracleConnection;
/**
 * OracleTarget
 * User: Ulysses
 * Date: 2007/6/15
 * Time: ?U?? 03:12:43
 * To change this template use File | Settings | File Templates.
 */
public class OracleTarget
{
    private static final Logger logger          = Logger.getLogger(OracleTarget.class);
    private static OracleTarget _instance       = null;
    private static final String ORACLE_URL      = "jdbc:oracle:thin:@";
    private static final String _propUsrKey     = "user";
    private static final String _propPassKey    = "password";
    private static String       _oracleHost     = "192.168.11.200";
    private static String       _oracleInstance = "NNTPC";
    private static String       _oraclePort     = "1521";
    static
    {
        try
        {
            DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        } catch (SQLException e)
        {
            Assert.shouldNeverReachHere(e.getMessage());
        }
    }
    private OracleConnection oracleConnection = null;
    private Properties       properties;
    private OracleTarget()
    {
        properties = new Properties();
        properties.put(_propUsrKey, "SPATIALDB");
        properties.put(_propPassKey, "SPATIALDB000");
    }
    public static String getOracleHost()
    {
        return _oracleHost;
    }
    public static void setOracleHost(String oracleHost)
    {
        OracleTarget._oracleHost = oracleHost;
    }
    public static String getOracleInstance()
    {
        return _oracleInstance;
    }
    public static void setOracleInstance(String oracleInstance)
    {
        OracleTarget._oracleInstance = oracleInstance;
    }
    public static String getOraclePort()
    {
        return _oraclePort;
    }
    public static void setOraclePort(String oraclePort)
    {
        OracleTarget._oraclePort = oraclePort;
    }
    public static String getCurrentURL()
    {
        StringBuilder builder = new StringBuilder();
        builder.append(ORACLE_URL);
        builder.append(_oracleHost);
        builder.append(":");
        builder.append(_oraclePort);
        builder.append(":");
        builder.append(_oracleInstance);
        return builder.toString();
    }
    public String getLoginPass()
    {
        return (String) properties.get(_propPassKey);
    }
    public void setLoginPass(String loginPass)
    {
        properties.put(_propPassKey, loginPass);
    }
    public String getLoginUsr()
    {
        return (String) properties.get(_propUsrKey);
    }
    public void setLoginUsr(String loginUsr)
    {
        properties.put(_propUsrKey, loginUsr);
    }
    public static OracleTarget getInstance()
    {
        if (_instance == null)
        {
            _instance = new OracleTarget();
        }
        return _instance;
    }
    public OracleConnection getOracleConnection()
    {
        try
        {
            if (oracleConnection == null)
            {
                oracleConnection = (OracleConnection) DriverManager.getConnection(getCurrentURL(), properties);
            }
            return oracleConnection;
        } catch (SQLException e)
        {
            logger.warn(e.getMessage(), e);
        }
        oracleConnection = null;
        return null;
    }
    public void closeConnection()
    {
        try
        {
            if (oracleConnection != null)
            {
                oracleConnection.close();
                oracleConnection = null;
            }
        } catch (SQLException e)
        {
            logger.warn(e.getMessage(), e);
        }
    }
}
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/Demo.dgn
Binary files differ
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88491-1.dgn
Binary files differ
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88491_0888888.dgn
Binary files differ
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/HV88494_0.dgn
Binary files differ
xdgnjobs/ximple-dgnio/src/test/resources/com/ximple/io/dgn7/test-data/testHV.dgn
Binary files differ
xdgnjobs/ximple-jobcarrier/pom.xml
New file
@@ -0,0 +1,141 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.ximple.eofms</groupId>
    <artifactId>ximple-dgnjobs</artifactId>
    <version>0.3.0</version>
  </parent>
  <groupId>com.ximple.eofms</groupId>
  <artifactId>ximple-jobcarrier</artifactId>
  <version>0.3.0</version>
  <packaging>jar</packaging>
  <name>ximple-jobcarrier</name>
  <url>http://maven.apache.org</url>
  <properties>
    <xdgnio.version>0.3.0</xdgnio.version>
  </properties>
  <scm>
    <connection>
      scm:svn:http://www.ximple.com.tw/svn/xeofms/xspatialjob/truck/
    </connection>
    <url>http://www.ximple.com.tw/svn/xeofms/xspatialjob/truck/</url>
  </scm>
  <description>
    Ximple Job Carrier for Quartz
  </description>
  <organization>
    <name>Ximple</name>
    <url>http://www.ximple.com.tw</url>
  </organization>
  <inceptionYear>2008</inceptionYear>
  <developers>
    <developer>
      <name>Kuo-Feng Kao</name>
      <id>ulysseskao</id>
      <email>ulysseskao@ximple.com.tw</email>
      <organization>Ximple</organization>
      <roles>
        <role>Java Developer</role>
      </roles>
    </developer>
  </developers>
  <contributors>
  </contributors>
  <!-- =========================================================== -->
  <!--     Dependencies to be inherited by all modules.            -->
  <!-- =========================================================== -->
  <dependencies>
    <dependency>
      <artifactId>quartz</artifactId>
      <groupId>opensymphony</groupId>
    </dependency>
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.0.1B</version>
    </dependency>
    <!-- Ximple Library -->
    <dependency>
      <artifactId>ximple-dgnio</artifactId>
      <groupId>com.ximple.eofms</groupId>
      <version>${xdgnio.version}</version>
    </dependency>
    <dependency>
      <artifactId>ximple-spatialjob</artifactId>
      <groupId>com.ximple.eofms</groupId>
      <version>${xdgnio.version}</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <!-- ======================================================= -->
      <!--     JAR packaging.                                      -->
      <!-- ======================================================= -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <mainClass>com.ximple.eofms.XQuartzJobCarrier</mainClass>
              <addClasspath>true</addClasspath>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <!-- ======================================================= -->
      <!--     exec jar.                                           -->
      <!-- ======================================================= -->
      <plugin>
        <!--
           Use maven from the command line:
             mvn exec:java -Dexec.mainClass="com.ximple.eofms.XQuartzJobCarrier"
        -->
        <artifactId>exec-maven-plugin</artifactId>
        <groupId>org.codehaus.mojo</groupId>
        <!--
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>run</goal>
            </goals>
          </execution>
        </executions>
        -->
        <configuration>
          <mainClass>com.ximple.eofms.XQuartzJobCarrier</mainClass>
        </configuration>
        <!--
        <dependencies>
          <dependency>
             <groupId>com.ximple.eofms</groupId>
             <artifactId>ximple-jobcarrier</artifactId>
             <version>0.0.1</version>
             <type>jar</type>
           </dependency>
        </dependencies>
        -->
      </plugin>
    </plugins>
    <resources>
    </resources>
  </build>
</project>
xdgnjobs/ximple-jobcarrier/src/main/java/com/ximple/eofms/XQuartzJobCarrier.java
New file
@@ -0,0 +1,95 @@
package com.ximple.eofms;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
import com.ximple.eofms.jobs.OracleConvertDgn2ShpJob;
/**
 * Hello world!
 */
public class XQuartzJobCarrier
{
    static Log logger = LogFactory.getLog(XQuartzJobCarrier.class);
    public static void main(String[] args)
    {
        XQuartzJobCarrier instance = new XQuartzJobCarrier();
        instance.startScheduler();
    }
    public void startScheduler()
    {
        Scheduler scheduler = null;
        boolean shutdown = false;
        try
        {
            // Get a Scheduler instance from the Factory
            scheduler = StdSchedulerFactory.getDefaultScheduler();
            // Start the scheduler
            scheduler.start();
            logger.info("Scheduler started at " + new Date());
        } catch (SchedulerException ex)
        {
            // deal with any exceptions
            logger.error(ex);
            shutdown = true;
        } catch (Throwable throwable)
        {
            logger.error(throwable.getMessage(), throwable);
            shutdown = true;
        }
        if (shutdown)
        {
            try
            {
                scheduler.shutdown();
            } catch (SchedulerException e)
            {
                logger.error(e.getMessage(), e);
            }
        }
    }
    /*
     * return an instance of the Scheduler from the factory
     */
    public Scheduler createScheduler() throws SchedulerException
    {
        return StdSchedulerFactory.getDefaultScheduler();
    }
    // Create and Schedule a ScanDirectoryJob with the Scheduler
    private void scheduleJob(Scheduler scheduler) throws SchedulerException
    {
        // Create a JobDetail for the Job
        JobDetail jobDetail = new JobDetail("ScanDirectory", Scheduler.DEFAULT_GROUP,
                OracleConvertDgn2ShpJob.class);
        // Configure the directory to scan
        jobDetail.getJobDataMap().put("SCAN_DIR", "c:\\quartz-book\\input");
        // Create a trigger that fires every 10 seconds, forever
        Trigger trigger = TriggerUtils.makeSecondlyTrigger(10);
        trigger.setName("scanTrigger");
        // Start the trigger firing from now
        trigger.setStartTime(new Date());
        // Associate the trigger with the job in the scheduler
        scheduler.scheduleJob(jobDetail, trigger);
    }
}
xdgnjobs/ximple-jobcarrier/src/main/resources/log4j.properties
New file
@@ -0,0 +1,28 @@
# Create stdout appender
log4j.rootLogger=error, logfile, stdout
# Configure the stdout appender to go to the Console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# Configure stdout appender to use the PatternLayout
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern output the caller's filename and line #
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
#log4j.appender.stdout.encoding=UTF-8
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.file=xjobcarrier.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
#log4j.appender.logfile.encoding=UTF-8
log4j.appender.remoteout=com.holub.log4j.RemoteAppender
log4j.appender.remoteout.Port=8011
log4j.appender.remoteout.layout=org.apache.log4j.PatternLayout
log4j.appender.remoteout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
#log4j.appender.remoteout.encoding=UTF-8
# Print messages of level INFO or above for examples
log4j.logger.org.cavaness.quartzbook=INFO
log4j.logger.com.ximple.eofms=INFO
xdgnjobs/ximple-jobcarrier/src/main/resources/quartz.properties
New file
@@ -0,0 +1,28 @@
#===============================================================
#Configure Main Scheduler Properties
#===============================================================
org.quartz.scheduler.instanceName = QuartzScheduler
org.quartz.scheduler.instanceId = AUTO
#===============================================================
#Configure ThreadPool
#===============================================================
org.quartz.threadPool.threadCount =  5
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
#===============================================================
#Configure JobStore
#===============================================================
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
#===============================================================
#Configure Plugins
#===============================================================
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.fileName = quartz_jobs.xml
org.quartz.plugin.jobInitializer.overWriteExistingJobs = true
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
org.quartz.plugin.jobInitializer.validating=false
xdgnjobs/ximple-jobcarrier/src/main/resources/quartz_jobs.xml
New file
@@ -0,0 +1,99 @@
<?xml version='1.0' encoding='utf-8'?>
<quartz xmlns="http://www.opensymphony.com/quartz/JobSchedulingData"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.opensymphony.com/quartz/JobSchedulingData
        http://www.opensymphony.com/quartz/xml/job_scheduling_data_1_5.xsd"
        version="1.5">
  <job>
    <job-detail>
      <name>ConvertDgn2ShpIntoDirectory</name>
      <group>DEFAULT</group>
      <description>A job that convert dgn to shapefiles</description>
      <job-class>com.ximple.eofms.jobs.OracleConvertDgn2ShpJob</job-class>
      <volatility>false</volatility>
      <durability>false</durability>
      <recover>false</recover>
      <job-data-map allows-transient-data="true">
        <entry>
          <key>SHPDATA_DIR</key>
          <value>g:\temp\data</value>
        </entry>
        <!--
        <entry>
          <key>SHPFILTER_CONF</key>
          <value></value>
        </entry>
        -->
        <entry>
          <key>ORAHOST</key>
          <value>192.168.11.200</value>
        </entry>
        <entry>
          <key>ORAINST</key>
          <value>nntpc</value>
        </entry>
        <entry>
          <key>ORAPORT</key>
          <value>1521</value>
        </entry>
        <entry>
          <key>ORAUSER</key>
          <value>spatialdb</value>
        </entry>
        <entry>
          <key>ORAPASS</key>
          <value>spatialdb000</value>
        </entry>
        <entry>
          <key>ORGSCHEMA</key>
          <value>SPATIALDB, CMMS_SPATIALDB</value>
        </entry>
        <entry>
          <key>CONVERTDB</key>
          <value>false</value>
        </entry>
        <entry>
          <key>CONVERTFILE</key>
          <value>false</value>
        </entry>
        <entry>
          <key>CONVERTELEMIN</key>
          <value>false</value>
        </entry>
        <entry>
          <key>CREATEDUMMY</key>
          <value>true</value>
        </entry>
        <entry>
          <key>ELEMLOG</key>
          <value>true</value>
        </entry>
        <entry>
          <key>TESTMODE</key>
          <value>FALSE</value>
        </entry>
        <entry>
          <key>TESTCOUNT</key>
          <value>2</value>
        </entry>
      </job-data-map>
    </job-detail>
    <trigger>
      <simple>
        <name>convertTrigger</name>
        <group>DEFAULT</group>
        <job-name>ConvertDgn2ShpIntoDirectory</job-name>
        <job-group>DEFAULT</job-group>
        <start-time>2008-03-01T18:10:00</start-time>
        <!-- repeat indefinitely every 10 seconds -->
        <repeat-count>0</repeat-count>
        <repeat-interval>500</repeat-interval>
        <!-- <repeat-interval>72000000</repeat-interval> -->
      </simple>
    </trigger>
  </job>
</quartz>
xdgnjobs/ximple-jobcarrier/src/test/java/com/ximple/eofms/XQuartzJobCarrierTest.java
New file
@@ -0,0 +1,19 @@
package com.ximple.eofms;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
 * Unit test for simple App.
 */
public class XQuartzJobCarrierTest
{
    /**
     * Rigourous Test :-)
     */
    @Test
    public void testApp()
    {
        Assert.assertTrue(true);
    }
}
xdgnjobs/ximple-spatialjob/pom.xml
New file
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.ximple.eofms</groupId>
    <artifactId>ximple-dgnjobs</artifactId>
    <version>0.3.0</version>
  </parent>
  <groupId>com.ximple.eofms</groupId>
  <artifactId>ximple-spatialjob</artifactId>
  <version>0.3.0</version>
  <packaging>jar</packaging>
  <name>ximple-spatialjob</name>
  <url>http://www.ximple.com.tw</url>
  <properties>
    <xdgnio.version>0.3.0</xdgnio.version>
  </properties>
  <description>
    Ximple Spatial Data Job for Quartz
  </description>
  <organization>
    <name>Ximple</name>
    <url>http://www.ximple.com.tw</url>
  </organization>
  <inceptionYear>2008</inceptionYear>
  <developers>
    <developer>
      <name>Kuo-Feng Kao</name>
      <id>ulysseskao</id>
      <email>ulysseskao@ximple.com.tw</email>
      <organization>Ximple</organization>
      <roles>
        <role>Java Developer</role>
      </roles>
    </developer>
  </developers>
  <contributors>
  </contributors>
  <!-- =========================================================== -->
  <!--     Dependencies to be inherited by all modules.            -->
  <!-- =========================================================== -->
  <dependencies>
    <dependency>
      <artifactId>quartz</artifactId>
      <groupId>opensymphony</groupId>
    </dependency>
    <!-- Ximple Library -->
    <dependency>
      <groupId>com.ximple.eofms</groupId>
      <artifactId>ximple-dgnio</artifactId>
      <version>${xdgnio.version}</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
    </plugins>
    <resources>
    </resources>
  </build>
</project>
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/AbstractDispatchableFilter.java
New file
@@ -0,0 +1,75 @@
package com.ximple.eofms.filter;
import java.util.LinkedList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.ximple.io.dgn7.Element;
public abstract class AbstractDispatchableFilter implements ElementDispatchableFilter
{
    private String name;
    private String description;
    private LinkedList<ElementTypeCriterion> typeIdCriterions;
    private LinkedList<ElementLevelCriterion> levelCriterions;
    protected Log logger = LogFactory.getLog(AbstractFLinkageDispatchableFilter.class);
    public AbstractDispatchableFilter()
    {
        typeIdCriterions = new LinkedList<ElementTypeCriterion>();
        levelCriterions = new LinkedList<ElementLevelCriterion>();
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public String getDescription()
    {
        return description;
    }
    public void setDescription(String description)
    {
        this.description = description;
    }
    public void addCriterion(ElementTypeCriterion criterion)
    {
        typeIdCriterions.add(criterion);
    }
    public void addLevelCriterion(ElementLevelCriterion criterion)
    {
        levelCriterions.add(criterion);
    }
    protected int compareType(Element element)
    {
        for (ElementTypeCriterion criterion : typeIdCriterions)
        {
            if (criterion.compareTo(element) == 0)
                return 0;
        }
        return -1;
    }
    protected int compareLevel(Element element)
    {
        for (ElementLevelCriterion criterion : levelCriterions)
        {
            if (criterion.compareTo(element) == 0)
                return 0;
        }
        return -1;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/AbstractFLinkageDispatchableFilter.java
New file
@@ -0,0 +1,26 @@
package com.ximple.eofms.filter;
import java.util.List;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.UserAttributeData;
public abstract class AbstractFLinkageDispatchableFilter extends AbstractDispatchableFilter
{
    public static FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateArcLineStringStrategy.java
New file
@@ -0,0 +1,96 @@
package com.ximple.eofms.filter;
import java.util.List;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.jobs.TWD97GeometryConverterDecorator;
import com.ximple.eofms.util.DefaultColorTable;
import com.ximple.io.dgn7.ArcElement;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.UserAttributeData;
public class CreateArcLineStringStrategy implements CreateFeatureTypeStrategy
{
    static final Log logger = LogFactory.getLog(CreateLineStringStrategy.class);
    GeometryFactory geometryFactory = new GeometryFactory();
    TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>();
    TWD97GeometryConverterDecorator convertDecorator = new TWD97GeometryConverterDecorator();
    public CreateArcLineStringStrategy()
    {
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
    public FeatureType createFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("TID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("OID", Long.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("CID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LEVEL", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        FrammeAttributeData fLinkage = getFeatureLinkage(element);
        if (fLinkage == null) return null;
        if (element instanceof ArcElement)
        {
            ArcElement lineStringElement = (ArcElement) element;
            convertDecorator.setConverter(lineStringElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    lineStringElement.getLevelIndex(),
                    colorTable.getColorCode(lineStringElement.getColorIndex()),
                    lineStringElement.getWeight(),
                    lineStringElement.getLineStyle()
            });
            return feature;
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateEllipseShapeStrategy.java
New file
@@ -0,0 +1,97 @@
package com.ximple.eofms.filter;
import java.util.List;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.jobs.TWD97GeometryConverterDecorator;
import com.ximple.eofms.util.DefaultColorTable;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.EllipseElement;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.UserAttributeData;
public class CreateEllipseShapeStrategy implements CreateFeatureTypeStrategy
{
    static final Log logger = LogFactory.getLog(CreateShapeStrategy.class);
    GeometryFactory geometryFactory = new GeometryFactory();
    TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>();
    TWD97GeometryConverterDecorator convertDecorator = new TWD97GeometryConverterDecorator();
    public CreateEllipseShapeStrategy()
    {
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
    public FeatureType createFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("TID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("OID", Long.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("CID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LEVEL", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        FrammeAttributeData fLinkage = getFeatureLinkage(element);
        if (fLinkage == null) return null;
        if (element instanceof EllipseElement)
        {
            EllipseElement shapeElement = (EllipseElement) element;
            convertDecorator.setConverter(shapeElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    shapeElement.getLevelIndex(),
                    colorTable.getColorCode(shapeElement.getColorIndex()),
                    shapeElement.getWeight(),
                    shapeElement.getLineStyle()
            });
            return feature;
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateFeatureTypeStrategy.java
New file
@@ -0,0 +1,15 @@
package com.ximple.eofms.filter;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.ximple.io.dgn7.Element;
public interface CreateFeatureTypeStrategy
{
    public FeatureType createFeatureElement(String featureName) throws SchemaException;
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException;
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineStringStrategy.java
New file
@@ -0,0 +1,147 @@
package com.ximple.eofms.filter;
import java.util.List;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.jobs.TWD97GeometryConverterDecorator;
import com.ximple.eofms.util.DefaultColorTable;
import com.ximple.io.dgn7.ComplexChainElement;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.LineElement;
import com.ximple.io.dgn7.LineStringElement;
import com.ximple.io.dgn7.UserAttributeData;
import com.ximple.io.dgn7.ArcElement;
public class CreateLineStringStrategy implements CreateFeatureTypeStrategy
{
    static final Log logger = LogFactory.getLog(CreateLineStringStrategy.class);
    GeometryFactory geometryFactory = new GeometryFactory();
    TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>();
    TWD97GeometryConverterDecorator convertDecorator = new TWD97GeometryConverterDecorator();
    public CreateLineStringStrategy()
    {
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
    public FeatureType createFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("TID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("OID", Long.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("CID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LEVEL", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        FrammeAttributeData fLinkage = getFeatureLinkage(element);
        if (fLinkage == null) return null;
        if (element instanceof LineStringElement)
        {
            LineStringElement lineStringElement = (LineStringElement) element;
            convertDecorator.setConverter(lineStringElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    lineStringElement.getLevelIndex(),
                    colorTable.getColorCode(lineStringElement.getColorIndex()),
                    lineStringElement.getWeight(),
                    lineStringElement.getLineStyle()
            });
            return feature;
        } else if (element instanceof ComplexChainElement)
        {
            ComplexChainElement complexChain = (ComplexChainElement) element;
            convertDecorator.setConverter(complexChain);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    complexChain.getLevelIndex(),
                    colorTable.getColorCode(complexChain.getColorIndex()),
                    complexChain.getWeight(),
                    complexChain.getLineStyle()
            });
            return feature;
        } else if (element instanceof LineElement)
        {
            LineElement lineElement = (LineElement) element;
            convertDecorator.setConverter(lineElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    lineElement.getLevelIndex(),
                    colorTable.getColorCode(lineElement.getColorIndex()),
                    lineElement.getWeight(),
                    lineElement.getLineStyle()
            });
            return feature;
        } else if (element instanceof ArcElement)
        {
            ArcElement lineStringElement = (ArcElement) element;
            convertDecorator.setConverter(lineStringElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    lineStringElement.getLevelIndex(),
                    colorTable.getColorCode(lineStringElement.getColorIndex()),
                    lineStringElement.getWeight(),
                    lineStringElement.getLineStyle()
            });
            return feature;
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineTextStrategy.java
New file
@@ -0,0 +1,164 @@
package com.ximple.eofms.filter;
import java.util.List;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.ximple.eofms.jobs.TWD97GeometryConverterDecorator;
import com.ximple.eofms.util.DefaultColorTable;
import com.ximple.eofms.util.TWDDatumConverter;
import com.ximple.io.dgn7.ComplexChainElement;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.LineElement;
import com.ximple.io.dgn7.LineStringElement;
import com.ximple.io.dgn7.TextElement;
import com.ximple.io.dgn7.UserAttributeData;
public class CreateLineTextStrategy implements CreateFeatureTypeStrategy
{
    static final Log logger = LogFactory.getLog(CreateLineTextStrategy.class);
    GeometryFactory geometryFactory = new GeometryFactory();
    TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>();
    TWD97GeometryConverterDecorator convertDecorator = new TWD97GeometryConverterDecorator();
    public CreateLineTextStrategy()
    {
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
    public FeatureType createFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("TID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("OID", Long.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("CID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LEVEL", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        FrammeAttributeData fLinkage = getFeatureLinkage(element);
        if (fLinkage == null) return null;
        if (element instanceof LineStringElement)
        {
            LineStringElement lineStringElement = (LineStringElement) element;
            convertDecorator.setConverter(lineStringElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    lineStringElement.getLevelIndex(),
                    colorTable.getColorCode(lineStringElement.getColorIndex()),
                    lineStringElement.getWeight(),
                    lineStringElement.getLineStyle()
            });
            return feature;
        } else if (element instanceof TextElement)
        {
            TextElement txtElement = (TextElement) element;
            Coordinate ptOrigin = txtElement.getUserOrigin();
            Coordinate ptEnd = new Coordinate();
            ptEnd.x = ptOrigin.x;
            ptEnd.y = ptOrigin.y + txtElement.getTextHeight();
            Coordinate[] vect = new Coordinate[2];
            vect[0] = TWDDatumConverter.fromTM2ToTWD97(ptOrigin);
            vect[1] = TWDDatumConverter.fromTM2ToTWD97(ptEnd);
            LineString line = geometryFactory.createLineString(vect);
            // convertDecorator.setConverter(txtElement);
            // Geometry geom = convertDecorator.toGeometry(geometryFactory);
            txtElement.getRotationAngle();
            Feature feature = featureType.create(new Object[]{
                    line,
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    txtElement.getLevelIndex(),
                    colorTable.getColorCode(txtElement.getColorIndex()),
                    txtElement.getWeight(),
                    txtElement.getLineStyle()
            });
            return feature;
        } else if (element instanceof ComplexChainElement)
        {
            ComplexChainElement complexChain = (ComplexChainElement) element;
            convertDecorator.setConverter(complexChain);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    complexChain.getLevelIndex(),
                    colorTable.getColorCode(complexChain.getColorIndex()),
                    complexChain.getWeight(),
                    complexChain.getLineStyle()
            });
            return feature;
        } else if (element instanceof LineElement)
        {
            LineElement lineElement = (LineElement) element;
            convertDecorator.setConverter(lineElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    lineElement.getLevelIndex(),
                    colorTable.getColorCode(lineElement.getColorIndex()),
                    lineElement.getWeight(),
                    lineElement.getLineStyle()
            });
            return feature;
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateShapeStrategy.java
New file
@@ -0,0 +1,112 @@
package com.ximple.eofms.filter;
import java.util.List;
import java.util.TreeMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.jobs.TWD97GeometryConverterDecorator;
import com.ximple.eofms.util.DefaultColorTable;
import com.ximple.io.dgn7.ComplexShapeElement;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.ShapeElement;
import com.ximple.io.dgn7.UserAttributeData;
public class CreateShapeStrategy implements CreateFeatureTypeStrategy
{
    static final Log logger = LogFactory.getLog(CreateShapeStrategy.class);
    GeometryFactory geometryFactory = new GeometryFactory();
    TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>();
    TWD97GeometryConverterDecorator convertDecorator = new TWD97GeometryConverterDecorator();
    public CreateShapeStrategy()
    {
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
    public FeatureType createFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("TID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("OID", Long.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("CID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LEVEL", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        FrammeAttributeData fLinkage = getFeatureLinkage(element);
        if (fLinkage == null) return null;
        if (element instanceof ShapeElement)
        {
            ShapeElement shapeElement = (ShapeElement) element;
            convertDecorator.setConverter(shapeElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    shapeElement.getLevelIndex(),
                    colorTable.getColorCode(shapeElement.getColorIndex()),
                    shapeElement.getWeight(),
                    shapeElement.getLineStyle()
            });
            return feature;
        } else if (element instanceof ComplexShapeElement)
        {
            ComplexShapeElement complexShape = (ComplexShapeElement) element;
            convertDecorator.setConverter(complexShape);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    complexShape.getLevelIndex(),
                    colorTable.getColorCode(complexShape.getColorIndex()),
                    complexShape.getWeight(),
                    complexShape.getLineStyle()
            });
            return feature;
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateSymbolStrategy.java
New file
@@ -0,0 +1,126 @@
package com.ximple.eofms.filter;
import java.util.List;
import java.util.TreeMap;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.jobs.TWD97GeometryConverterDecorator;
import com.ximple.eofms.util.DefaultColorTable;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.TextElement;
import com.ximple.io.dgn7.UserAttributeData;
public class CreateSymbolStrategy implements CreateFeatureTypeStrategy
{
    static final Log logger = LogFactory.getLog(CreateSymbolStrategy.class);
    GeometryFactory geometryFactory = new GeometryFactory();
    TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>();
    TWD97GeometryConverterDecorator convertDecorator = new TWD97GeometryConverterDecorator();
    public CreateSymbolStrategy()
    {
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
    public FeatureType createFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("TID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("OID", Long.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("CID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LEVEL", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("JUST", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("HEIGHT", Double.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("WIDTH", Double.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("ANGLE", Double.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMBOL", String.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        FrammeAttributeData fLinkage = getFeatureLinkage(element);
        if (fLinkage == null) return null;
        if (element instanceof TextElement)
        {
            TextElement txtElement = (TextElement) element;
            double angle = txtElement.getRotationAngle();
            angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue();
            if (txtElement.getText().length() == 0)
            {
                logger.info("CreateSymbolStrategy cannot conver " + element.toString() +
                        "to Feature - getText() is empty.");
                return null;
            }
            StringBuilder sb = new StringBuilder();
            sb.append("OCT");
            char id = txtElement.getText().toCharArray()[0];
            sb.append(Integer.toOctalString((int) id));
            sb.append("-");
            sb.append(txtElement.getFontIndex());
            convertDecorator.setConverter(txtElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    txtElement.getLevelIndex(),
                    colorTable.getColorCode(txtElement.getColorIndex()),
                    txtElement.getWeight(),
                    txtElement.getLineStyle(),
                    txtElement.getJustification(),
                    txtElement.getTextHeight(),
                    txtElement.getTextWidth(),
                    angle,
                    sb.toString()
            });
            return feature;
        } else
        {
            logger.info("CreateSymbolStrategy cannot conver " + element.toString() + "to Feature");
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateTextStrategy.java
New file
@@ -0,0 +1,142 @@
package com.ximple.eofms.filter;
import java.util.List;
import java.util.TreeMap;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.jobs.TWD97GeometryConverterDecorator;
import com.ximple.eofms.util.DefaultColorTable;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.TextElement;
import com.ximple.io.dgn7.TextNodeElement;
import com.ximple.io.dgn7.UserAttributeData;
public class CreateTextStrategy implements CreateFeatureTypeStrategy
{
    static final Log logger = LogFactory.getLog(CreateTextStrategy.class);
    GeometryFactory geometryFactory = new GeometryFactory();
    TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>();
    TWD97GeometryConverterDecorator convertDecorator = new TWD97GeometryConverterDecorator();
    public CreateTextStrategy()
    {
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
    public FeatureType createFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("TID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("OID", Long.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("CID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LID", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("LEVEL", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("JUST", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("HEIGHT", Double.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("WIDTH", Double.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("ANGLE", Double.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("CONTEXT", String.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        FrammeAttributeData fLinkage = getFeatureLinkage(element);
        if (fLinkage == null) return null;
        if (element instanceof TextElement)
        {
            TextElement txtElement = (TextElement) element;
            double angle = txtElement.getRotationAngle();
            angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue();
            convertDecorator.setConverter(txtElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    txtElement.getLevelIndex(),
                    colorTable.getColorCode(txtElement.getColorIndex()),
                    txtElement.getWeight(),
                    txtElement.getLineStyle(),
                    txtElement.getJustification(),
                    txtElement.getTextHeight(),
                    txtElement.getTextWidth(),
                    angle,
                    txtElement.getText()
            });
            return feature;
        } else if (element instanceof TextNodeElement)
        {
            TextNodeElement nodeElement = (TextNodeElement) element;
            String[] texts = nodeElement.getTextArray();
            StringBuffer sb = new StringBuffer();
            for (String text : texts)
            {
                if (sb.length() != 0)
                    sb.append("\n");
                sb.append(text);
            }
            double angle = nodeElement.getRotationAngle();
            angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue();
            convertDecorator.setConverter(nodeElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    (int) fLinkage.getFsc(),
                    (long) fLinkage.getUfid(),
                    (int) fLinkage.getComponentID(),
                    0,
                    nodeElement.getLevelIndex(),
                    colorTable.getColorCode(nodeElement.getColorIndex()),
                    nodeElement.getWeight(),
                    nodeElement.getLineStyle(),
                    nodeElement.getJustification(),
                    nodeElement.getTextNodeHeight(),
                    nodeElement.getTextNodeLength(),
                    angle,
                    sb.toString()
            });
            return feature;
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementDispatchableFilter.java
New file
@@ -0,0 +1,12 @@
package com.ximple.eofms.filter;
import org.geotools.feature.Feature;
import com.ximple.io.dgn7.Element;
public interface ElementDispatchableFilter
{
    public boolean isDispatchable(Element element);
    public Feature execute(Element element);
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementDispatcher.java
New file
@@ -0,0 +1,39 @@
package com.ximple.eofms.filter;
import java.util.LinkedList;
import org.geotools.feature.Feature;
import com.ximple.io.dgn7.Element;
public class ElementDispatcher
{
    private LinkedList<ElementDispatchableFilter> rules;
    public ElementDispatcher()
    {
        rules = new LinkedList<ElementDispatchableFilter>();
    }
    public LinkedList<ElementDispatchableFilter> getRules()
    {
        return rules;
    }
    public void addRule(ElementDispatchableFilter rule)
    {
        rules.add(rule);
    }
    public Feature execute(Element element)
    {
        for (ElementDispatchableFilter rule : rules)
        {
            if (rule.isDispatchable(element))
            {
                return rule.execute(element);
            }
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementLevelCriterion.java
New file
@@ -0,0 +1,48 @@
package com.ximple.eofms.filter;
import java.util.ArrayList;
import com.ximple.io.dgn7.Element;
public class ElementLevelCriterion implements Comparable
{
    private int elementLevel;
    private ArrayList<Integer> elementLevelArray;
    public ElementLevelCriterion()
    {
        elementLevelArray = new ArrayList<Integer>();
    }
    public int compareTo(Object o)
    {
        if (o instanceof Element)
        {
            Element elm = (Element) o;
            for (Integer elevel : getElementLevelArray())
            {
                if (elm.getElementType().id == elevel.intValue())
                    return 0;
            }
        }
        return -1;
    }
    public int getElementLevel()
    {
        return elementLevel;
    }
    public ArrayList<Integer> getElementLevelArray()
    {
        return elementLevelArray;
    }
    public void setElementLevel(int iLevel)
    {
        this.elementLevel = iLevel;
        this.elementLevelArray.add(iLevel);
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/ElementTypeCriterion.java
New file
@@ -0,0 +1,48 @@
package com.ximple.eofms.filter;
import java.util.ArrayList;
import com.ximple.io.dgn7.Element;
public class ElementTypeCriterion implements Comparable
{
    private int elementType;
    private ArrayList<Integer> elementTypeArray;
    public ElementTypeCriterion()
    {
        elementTypeArray = new ArrayList<Integer>();
    }
    public int compareTo(Object o)
    {
        if (o instanceof Element)
        {
            Element elm = (Element) o;
            for (Integer etype : getElementTypeArray())
            {
                if (elm.getElementType().id == etype.intValue())
                    return 0;
            }
        }
        return -1;
    }
    public int getElementType()
    {
        return elementType;
    }
    public ArrayList<Integer> getElementTypeArray()
    {
        return elementTypeArray;
    }
    public void setElementType(int itype)
    {
        this.elementType = itype;
        this.elementTypeArray.add(itype);
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/TypeCompIdDispatchableFilter.java
New file
@@ -0,0 +1,101 @@
package com.ximple.eofms.filter;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
public class TypeCompIdDispatchableFilter extends AbstractFLinkageDispatchableFilter
{
    private int tid;
    private int cid;
    private CreateFeatureTypeStrategy createStrategy;
    public TypeCompIdDispatchableFilter()
    {
    }
    public TypeCompIdDispatchableFilter(String fname,
                                        CreateFeatureTypeStrategy createStrategy,
                                        int tid, int compid)
    {
        this.setName(fname);
        this.tid = tid;
        this.cid = compid;
        this.createStrategy = createStrategy;
    }
    public int getTid()
    {
        return tid;
    }
    public void setTid(int tid)
    {
        this.tid = tid;
    }
    public int getCid()
    {
        return cid;
    }
    public void setCid(int cid)
    {
        this.cid = cid;
    }
    public CreateFeatureTypeStrategy getCreateStrategy()
    {
        return createStrategy;
    }
    public void setCreateStrategy(CreateFeatureTypeStrategy createStrategy)
    {
        this.createStrategy = createStrategy;
    }
    //§PÂ_¬O§_²Å©M±ø¥ó
    public boolean isDispatchable(Element element)
    {
        FrammeAttributeData featureLinkage = getFeatureLinkage(element);
        return featureLinkage != null && tid == featureLinkage.getFsc() &&
                (cid == featureLinkage.getComponentID()) &&
                (compareType(element) == 0);
    }
    public Feature execute(Element element)
    {
        try
        {
            String ftName = getFeatureTypeName(element);
            FeatureType ftype = createStrategy.createFeatureElement(ftName);
            return createStrategy.createFeature(ftype, element);
        } catch (SchemaException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IllegalAttributeException e)
        {
            logger.error(e.getMessage(), e);
        } catch (NullPointerException e)
        {
            logger.error(e.getMessage(), e);
        }
        return null;
    }
    public String getFeatureTypeName(Element element)
    {
        StringBuilder sb= new StringBuilder();
        sb.append(getName());
        sb.append("_");
        sb.append(element.getLevelIndex());
        sb.append("_");
        sb.append(element.getWeight());
        return sb.toString();
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/TypeCompLevelIdDispatchableFilter.java
New file
@@ -0,0 +1,108 @@
package com.ximple.eofms.filter;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
public class TypeCompLevelIdDispatchableFilter extends AbstractFLinkageDispatchableFilter
{
    private int tid;
    private int cid;
    private int lid;
    private CreateFeatureTypeStrategy createStrategy;
    public TypeCompLevelIdDispatchableFilter()
    {
    }
    public TypeCompLevelIdDispatchableFilter(String fname,
                                             CreateFeatureTypeStrategy createStrategy,
                                             int tid, int compid, int level)
    {
        this.setName(fname);
        this.tid = tid;
        this.cid = compid;
        this.lid = level;
        this.createStrategy = createStrategy;
    }
    public int getTid()
    {
        return tid;
    }
    public void setTid(int tid)
    {
        this.tid = tid;
    }
    public int getCid()
    {
        return cid;
    }
    public void setCid(int cid)
    {
        this.cid = cid;
    }
    public int getLid()
    {
        return lid;
    }
    public void setLid(int lid)
    {
        this.lid = lid;
    }
    public CreateFeatureTypeStrategy getCreateStrategy()
    {
        return createStrategy;
    }
    public void setCreateStrategy(CreateFeatureTypeStrategy createStrategy)
    {
        this.createStrategy = createStrategy;
    }
    public boolean isDispatchable(Element element)
    {
        FrammeAttributeData featureLinkage = getFeatureLinkage(element);
        return featureLinkage != null && tid == featureLinkage.getFsc() &&
                (cid == featureLinkage.getComponentID()) &&
                (lid == element.getLevelIndex()) && (compareLevel(element) == 0);
    }
    public Feature execute(Element element)
    {
        try
        {
            String ftName = getFeatureTypeName(element);
            FeatureType ftype = createStrategy.createFeatureElement(ftName);
            return createStrategy.createFeature(ftype, element);
        } catch (SchemaException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IllegalAttributeException e)
        {
            logger.error(e.getMessage(), e);
        }
        return null;
    }
    public String getFeatureTypeName(Element element)
    {
        StringBuilder sb= new StringBuilder();
        sb.append(getName());
        sb.append("_");
        sb.append(element.getLevelIndex());
        sb.append("_");
        sb.append(element.getWeight());
        return sb.toString();
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/TypeIdDispatchableFilter.java
New file
@@ -0,0 +1,82 @@
package com.ximple.eofms.filter;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
public class TypeIdDispatchableFilter extends AbstractFLinkageDispatchableFilter
{
    private int tid;
    private CreateFeatureTypeStrategy createStrategy;
    public TypeIdDispatchableFilter()
    {
    }
    public TypeIdDispatchableFilter(String fname, CreateFeatureTypeStrategy createStrategy,
                                    int tid)
    {
        this.setName(fname);
        this.tid = tid;
        this.createStrategy = createStrategy;
    }
    public int getTid()
    {
        return tid;
    }
    public void setTid(int tid)
    {
        this.tid = tid;
    }
    public CreateFeatureTypeStrategy getCreateStrategy()
    {
        return createStrategy;
    }
    public void setCreateStrategy(CreateFeatureTypeStrategy createStrategy)
    {
        this.createStrategy = createStrategy;
    }
    public boolean isDispatchable(Element element)
    {
        FrammeAttributeData featureLinkage = getFeatureLinkage(element);
        return featureLinkage != null && tid == featureLinkage.getFsc() &&
                (compareType(element) == 0);
    }
    public Feature execute(Element element)
    {
        try
        {
            String ftName = getFeatureTypeName(element);
            FeatureType ftype = createStrategy.createFeatureElement(ftName);
            return createStrategy.createFeature(ftype, element);
        } catch (SchemaException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IllegalAttributeException e)
        {
            logger.error(e.getMessage(), e);
        }
        return null;
    }
    public String getFeatureTypeName(Element element)
    {
        StringBuilder sb= new StringBuilder();
        sb.append(getName());
        sb.append("_");
        sb.append(element.getLevelIndex());
        sb.append("_");
        sb.append(element.getWeight());
        return sb.toString();
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/AbstractDgnFileJobContext.java
New file
@@ -0,0 +1,82 @@
package com.ximple.eofms.jobs;
import java.util.Properties;
import org.quartz.JobExecutionContext;
import com.ximple.io.dgn7.Dgn7fileReader;
public abstract class AbstractDgnFileJobContext
{
    /**
     * Encoding of URL path.
     */
    protected static final String ENCODING = "UTF-8";
    private JobExecutionContext executionContext = null;
    protected String _dataPath = null;
    protected Properties properties = null;
    private Dgn7fileReader reader = null;
    private String filename = null;
    private boolean _elementLogging;
    public AbstractDgnFileJobContext(String dataPath)
    {
        _dataPath = dataPath;
    }
    public String getDataPath()
    {
        return _dataPath;
    }
    public JobExecutionContext getExecutionContext()
    {
        return executionContext;
    }
    public void setExecutionContext(JobExecutionContext context)
    {
        executionContext = context;
    }
    public abstract void startTransaction();
    public abstract void commitTransaction();
    public abstract void rollbackTransaction();
    public abstract String getDataOutPath();
    public Dgn7fileReader getReader()
    {
        return this.reader;
    }
    public void setReader(Dgn7fileReader reader)
    {
        this.reader = reader;
    }
    public String getFilename()
    {
        return filename;
    }
    public void setFilename(String filename)
    {
        this.filename = filename;
    }
    public boolean getElementLogging()
    {
        return _elementLogging;
    }
    public void setElementLogging(boolean elementLogging)
    {
        this._elementLogging = elementLogging;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/AbstractOracleDatabaseJob.java
New file
@@ -0,0 +1,305 @@
package com.ximple.eofms.jobs;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.apache.commons.logging.Log;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.vividsolutions.jts.util.Assert;
import oracle.sql.BLOB;
public abstract class AbstractOracleDatabaseJob implements Job
{
    private static final String SHPDATA_DIR = "SHPDATA_DIR";
    private static final String CONFSHPFILTER = "SHPFILTER_CONF";
    private static final String SPATAILSCHEMA = "ORGSCHEMA";
    private static final String CONVERTDB = "CONVERTDB";
    private static final String CONVERTFILE = "CONVERTFILE";
    private static final String CONVERTELEMIN = "CONVERTELEMIN";
    private static final String CREATEDUMMY = "CREATEDUMMY";
    private static final String ELEMLOG = "ELEMLOG";
    private static final String ORAHOST = "ORAHOST";
    private static final String ORAINST = "ORAINST";
    private static final String ORAPORT = "ORAPORT";
    private static final String ORAUSER = "ORAUSER";
    private static final String ORAPASS = "ORAPASS";
    private static final String TESTMODE = "TESTMODE";
    private static final String TESTCOUNT = "TESTCOUNT";
    protected String _dataPath;
    protected String _filterPath;
    protected String _oracleHost;
    protected String _oracleInstance;
    protected String _oraclePort;
    protected String _username;
    protected String _password;
    protected String _convertDB;
    protected String _convertFile;
    protected String _convertElementIn;
    protected String _elementLogging;
    protected String _createDummy;
    protected ArrayList<String> _orgSchema = new ArrayList<String>();
    protected boolean _testMode = false;
    protected int _testCount = -1;
    public abstract void execute(JobExecutionContext context) throws JobExecutionException;
    public Log getLogger() { return null; }
    protected void extractJobConfiguration(JobDetail jobDetail) throws JobExecutionException
    {
        // The directory to scan is stored in the job map
        JobDataMap dataMap = jobDetail.getJobDataMap();
        _dataPath = dataMap.getString(SHPDATA_DIR);
        _filterPath = dataMap.getString(CONFSHPFILTER);
        _oracleHost = dataMap.getString(ORAHOST);
        _oracleInstance = dataMap.getString(ORAINST);
        _oraclePort = dataMap.getString(ORAPORT);
        _username = dataMap.getString(ORAUSER);
        _password = dataMap.getString(ORAPASS);
        _convertDB = dataMap.getString(CONVERTDB);
        _convertFile = dataMap.getString(CONVERTFILE);
        _convertElementIn = dataMap.getString(CONVERTELEMIN);
        _elementLogging = dataMap.getString(ELEMLOG);
        _createDummy = dataMap.getString(CREATEDUMMY);
        Log logger = getLogger();
        logger.info("SHPDATA_DIR=" + _dataPath);
        logger.info("CONFSHPFILTER=" + _filterPath);
        logger.info("ORAHOST=" + _oracleHost);
        logger.info("ORAINST=" + _oracleInstance);
        logger.info("ORAPORT=" + _oraclePort);
        logger.info("ORAUSER=" + _username);
        logger.info("ORAPASS=" + _password);
        logger.info("CONVERTDB=" + _convertDB);
        logger.info("CONVERTFILE=" + _convertFile);
        logger.info("CONVERTELEMIN=" + _convertElementIn);
        logger.info("ELEMLOG=" + _elementLogging);
        String strSchema = dataMap.getString(SPATAILSCHEMA);
        StringTokenizer st = new StringTokenizer(strSchema, ",");
        while (st.hasMoreTokens())
        {
            String aSchema = st.nextToken().trim();
            _orgSchema.add(aSchema);
        }
        _testMode = dataMap.getBooleanFromString(TESTMODE);
        _testCount = dataMap.getIntFromString(TESTCOUNT);
        // Validate the required input
        if (_dataPath == null)
        {
            if (logger != null)
            {
                logger.warn("Cannot found data directory in configarion.");
            }
            throw new JobExecutionException("Directory not configured");
        }
        // Make sure the directory exists
        File dir = new File(_dataPath);
        if (!dir.exists())
        {
            logger = getLogger();
            if (logger != null)
            {
                logger.warn("Cannot found data directory in file system.[" + _dataPath + "]");
            }
            throw new JobExecutionException("Invalid Dir " + _dataPath);
        }
        if (_oracleHost == null)
        {
            throw new JobExecutionException("Unknown Oracle Host.");
        }
        if (_oracleInstance == null)
        {
            throw new JobExecutionException("Unknown Oracle Instance.");
        }
        if (_username == null)
        {
            throw new JobExecutionException("Unknown Oracle Username.");
        }
        if (_password == null)
        {
            throw new JobExecutionException("Unknown Oracle Password.");
        }
        if (_orgSchema == null)
        {
            throw new JobExecutionException("Unknown Spatial Database Schema.");
        }
    }
    protected abstract AbstractOracleJobContext prepareJobContext(String filterPath);
    protected static byte[] getBytesFromBLOB(BLOB blob) throws SQLException
    {
        byte[] raw = null;
        // BLOB        blob        = (BLOB) rs.getBlob(1);
        int optimalSize = blob.getChunkSize();
        byte[] chunk = new byte[optimalSize];
        InputStream is = blob.getBinaryStream(0);
        ByteBuffer buffer = null;    // ByteBuffer.allocate(optimalSize);
        int len;
        try
        {
            while ((len = (is.read(chunk))) != -1)
            {
                if (buffer != null)
                {
                    buffer.limit(buffer.limit() + len);
                } else
                {
                    buffer = ByteBuffer.allocate(len);
                }
                buffer.put(chunk);
            }
            is.close();
            assert buffer != null;
            buffer.position(0);
            raw = buffer.array();
        } catch (IOException e)
        {
            e.printStackTrace();    // To change body of catch statement use File | Settings | File Templates.
            Assert.shouldNeverReachHere();
        }
        return raw;
    }
    public String getDataPath()
    {
        return _dataPath;
    }
    public String getFilterPath()
    {
        return _filterPath;
    }
    public String getOracleHost()
    {
        return _oracleHost;
    }
    public String getOracleInstance()
    {
        return _oracleInstance;
    }
    public String getOraclePort()
    {
        return _oraclePort;
    }
    public String getUsername()
    {
        return _username;
    }
    public String getPassword()
    {
        return _password;
    }
    public ArrayList<String> getOriginSchema()
    {
        return _orgSchema;
    }
    public boolean isTestMode()
    {
        return _testMode;
    }
    public int getTestCount()
    {
        return _testCount;
    }
    public String getConvertDB()
    {
        return _convertDB;
    }
    public void setConvertDB(String convertDB)
    {
        _convertDB = convertDB;
    }
    public String getConvertFile()
    {
        return _convertFile;
    }
    public void setConvertFile(String convertFile)
    {
        _convertFile = convertFile;
    }
    public String getConvertElementIn()
    {
        return _convertElementIn;
    }
    public void setConvertElementIn(String convertElementIn)
    {
        _convertElementIn = convertElementIn;
    }
    public boolean checkConvertDB()
    {
        return _convertDB != null && !_convertDB.equalsIgnoreCase("false") &&
                !_convertDB.equalsIgnoreCase("no") && !_convertDB.equalsIgnoreCase("0");
    }
    public boolean checkConvertFile()
    {
        return _convertFile != null && !_convertFile.equalsIgnoreCase("false") &&
                !_convertFile.equalsIgnoreCase("no") && !_convertFile.equalsIgnoreCase("0");
    }
    public boolean checkConvertElementIn()
    {
        return _convertElementIn != null && !_convertElementIn.equalsIgnoreCase("false") &&
                !_convertElementIn.equalsIgnoreCase("no") && !_convertElementIn.equalsIgnoreCase("0");
    }
    public String getElementLogging()
    {
        return _elementLogging;
    }
    public void setElementLogging(String elementLogging)
    {
        this._elementLogging = elementLogging;
    }
    public boolean checkElementLogging()
    {
        return _elementLogging != null && !_elementLogging.equalsIgnoreCase("false") &&
                !_elementLogging.equalsIgnoreCase("no") && !_elementLogging.equalsIgnoreCase("0");
    }
    public boolean checkCreateDummy()
    {
        return _createDummy != null && !_createDummy.equalsIgnoreCase("false") &&
                !_createDummy.equalsIgnoreCase("no") && !_createDummy.equalsIgnoreCase("0");
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/AbstractOracleJobContext.java
New file
@@ -0,0 +1,326 @@
package com.ximple.eofms.jobs;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import oracle.jdbc.OracleConnection;
public abstract class AbstractOracleJobContext
{
    private static final String ORACLE_URL = "jdbc:oracle:thin:@";
    private static final String PROPUsrKey = "user";
    private static final String PROPPassKey = "password";
    /**
     * Table Prefiex
     */
    protected static final String TABLE_PREFIX = "GEO$";
    protected static final String UDT_SCHEMA = "SPATIALDB";
    /**
     * User Types
     */
    protected static final String UDT_RAWS = "CREATE OR REPLACE TYPE \"" + UDT_SCHEMA + "\".\"RAWS\" AS VARRAY (1048576) OF NUMBER(38)";
    protected static final String UDT_OFMID = "CREATE OR REPLACE TYPE  \"" + UDT_SCHEMA + "\".\"OFMID\" AS OBJECT ("
            + "\"CLSID\" NUMBER(5), \"OID\" NUMBER(10), \"STATUS\" NUMBER(5), \"COMPID\" NUMBER(3), "
            + "\"RULEID\" NUMBER(3), \"OCCID\" NUMBER(3))";
    protected static final String UDT_RAWSNAME = "RAWS";
    protected static final String UDT_OFMIDNAME = "OFMID";
    /**
     * Utility SQL
     */
    protected static final String TAB_DROP = "DROP TABLE %s.%s CASCADE CONSTRAINTS";
    protected static final String TAB_DELETE = "DELETE FROM %s.%s";
    /**
     * Table Schema
     */
    protected static final String TAB_RANGENODEINDEX_1 = "CREATE TABLE \"%s\".\"%s\"\n"
            + "   (    \"RNID\" INTEGER NOT NULL ENABLE,\n"
            + "    \"RPID\" INTEGER NOT NULL ENABLE,\n"
            + "    \"RNG_LOWX\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"RNG_LOWY\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"RNG_HIGHX\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"RNG_HIGHY\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"EXTENTS\" MDSYS.SDO_GEOMETRY,\n"
            + "    \"RNDESCR\" VARCHAR2(255), \n"
            + "    PRIMARY KEY ( \"RNID\" ) ENABLE )";
    protected static final String TAB_RANGENODEINDEX = "CREATE TABLE \"%s\".\"%s\"\n"
            + "   (    \"RNID\" INTEGER NOT NULL ENABLE,\n"
            + "    \"RPID\" INTEGER NOT NULL ENABLE,\n"
            + "    \"RNG_LOWX\" FLOAT NOT NULL ENABLE,\n"
            + "    \"RNG_LOWY\" FLOAT NOT NULL ENABLE,\n"
            + "    \"RNG_HIGHX\" FLOAT NOT NULL ENABLE,\n"
            + "    \"RNG_HIGHY\" FLOAT NOT NULL ENABLE,\n"
            + "    \"RNDESCR\" VARCHAR2(255), \n"
            + "    PRIMARY KEY ( \"RNID\" ) ENABLE )";
    protected static final String TAB_RANGENODESTORAGE = "CREATE TABLE \"%s\".\"%s\"\n"
            + "   (    \"RNID\" INTEGER NOT NULL ENABLE,\n"
            + "    \"LAYERID\" NUMBER(5,0) NOT NULL ENABLE,\n"
            + "    \"LASTUPDATE\" DATE NOT NULL ENABLE,\n"
            + "    \"SPACETABLE\" VARCHAR2(255)\n" + "   )";
    protected static final String TAB_ELEMENTINDEX_1 = "CREATE TABLE %s.%s (\n"
            + "    \"ELMNO\" INTEGER NOT NULL ENABLE,\n"
            + "    \"TYPE\" NUMBER(5) NOT NULL ENABLE,\n"
            + "    \"XLOW\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"YLOW\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"ZLOW\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"XHIGH\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"YHIGH\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"ZHIGH\" BINARY_DOUBLE NOT NULL ENABLE,\n"
            + "    \"TAG_LUFID\" NUMBER(10) NOT NULL ENABLE,\n"
            + "    \"TAG_SFSC\" NUMBER(5) NOT NULL ENABLE,\n"
            + "    \"TAG_SSTAT\" NUMBER(5) NOT NULL ENABLE,\n"
            + "    \"TAG_BCOMPID\" NUMBER(3) NOT NULL ENABLE,\n"
            + "    \"TAG_BRULENO\" NUMBER(3) NOT NULL ENABLE,\n"
            + "    \"TAG_SOCCID\" NUMBER(5) NOT NULL ENABLE,\n"
            + "    \"SPACENAME\" VARCHAR2(255) NOT NULL ENABLE,\n"
            + "     PRIMARY KEY (\"ELMNO\") ENABLE\n"
            + "   )";
    protected static final String TAB_ELEMENTINDEX = "CREATE TABLE %s.%s (\n"
            + "    \"ELMNO\" INTEGER NOT NULL ENABLE,\n"
            + "    \"TYPE\" NUMBER(5) NOT NULL ENABLE,\n"
            + "    \"XLOW\" FLOAT NOT NULL ENABLE,\n"
            + "    \"YLOW\" FLOAT NOT NULL ENABLE,\n"
            + "    \"ZLOW\" FLOAT NOT NULL ENABLE,\n"
            + "    \"XHIGH\" FLOAT NOT NULL ENABLE,\n"
            + "    \"YHIGH\" FLOAT NOT NULL ENABLE,\n"
            + "    \"ZHIGH\" FLOAT NOT NULL ENABLE,\n"
            + "    \"TAG_LUFID\" NUMBER(10) NOT NULL ENABLE,\n"
            + "    \"TAG_SFSC\" NUMBER(5) NOT NULL ENABLE,\n"
            + "    \"TAG_SSTAT\" NUMBER(5) NOT NULL ENABLE,\n"
            + "    \"TAG_BCOMPID\" NUMBER(3) NOT NULL ENABLE,\n"
            + "    \"TAG_BRULENO\" NUMBER(3) NOT NULL ENABLE,\n"
            + "    \"TAG_SOCCID\" NUMBER(5) NOT NULL ENABLE,\n"
            + "    \"SPACENAME\" VARCHAR2(255) NOT NULL ENABLE,\n"
            + "     PRIMARY KEY (\"ELMNO\") ENABLE\n"
            + "   )";
    protected static final String TAB_IGDSSEED = "CREATE TABLE  %s.%s (\n"
            + "   \"ELMNO\" INTEGER NOT NULL ENABLE,\n"
            + "   \"SEEDELM\" \"" + UDT_SCHEMA
            + "\".\"RAWS\" NOT NULL ENABLE\n" + "   )";
    protected static final String TAB_STORAGE_1 = "CREATE TABLE %s.%s (\n" +
            "    \"ELMNO\" INTEGER NOT NULL ENABLE,\n" +
            "    \"XLOW\" BINARY_DOUBLE NOT NULL ENABLE,\n" +
            "    \"YLOW\" BINARY_DOUBLE NOT NULL ENABLE,\n" +
            "    \"XHIGH\" BINARY_DOUBLE NOT NULL ENABLE,\n" +
            "    \"YHIGH\" BINARY_DOUBLE NOT NULL ENABLE,\n" +
            "    \"EXTENTS\" MDSYS.SDO_GEOMETRY, \n" +
            "    \"PROPS\" INTEGER NOT NULL ENABLE,\n" +
            "    \"TAG_LUFID\" NUMBER(10) NOT NULL ENABLE,\n" +
            "    \"TAG_SFSC\" NUMBER(5) NOT NULL ENABLE,\n" +
            "    \"TAG_SSTAT\" NUMBER(5) NOT NULL ENABLE,\n" +
            "    \"TAG_BCOMPID\" NUMBER(3) NOT NULL ENABLE,\n" +
            "    \"TAG_BRULENO\" NUMBER(3) NOT NULL ENABLE,\n" +
            "    \"TAG_SOCCID\" NUMBER(5) NOT NULL ENABLE,\n" +
            "    \"LAYERID\" NUMBER(5) NOT NULL ENABLE,\n" +
            "    \"ELEMENT\" \"" + UDT_SCHEMA + "\".\"RAWS\" NOT NULL ENABLE, \n" +
            "    \"GEOM\" MDSYS.SDO_GEOMETRY \n" +
            "   )";
    protected static final String TAB_STORAGE = "CREATE TABLE %s.%s (\n" +
            "    \"ELMNO\" INTEGER NOT NULL ENABLE,\n" +
            "    \"XLOW\" FLOAT NOT NULL ENABLE,\n" +
            "    \"YLOW\" FLOAT NOT NULL ENABLE,\n" +
            "    \"XHIGH\" FLOAT NOT NULL ENABLE,\n" +
            "    \"YHIGH\" FLOAT NOT NULL ENABLE,\n" +
            "    \"PROPS\" INTEGER NOT NULL ENABLE,\n" +
            "    \"TAG_LUFID\" NUMBER(10) NOT NULL ENABLE,\n" +
            "    \"TAG_SFSC\" NUMBER(5) NOT NULL ENABLE,\n" +
            "    \"TAG_SSTAT\" NUMBER(5) NOT NULL ENABLE,\n" +
            "    \"TAG_BCOMPID\" NUMBER(3) NOT NULL ENABLE,\n" +
            "    \"TAG_BRULENO\" NUMBER(3) NOT NULL ENABLE,\n" +
            "    \"TAG_SOCCID\" NUMBER(5) NOT NULL ENABLE,\n" +
            "    \"LAYERID\" NUMBER(5) NOT NULL ENABLE,\n" +
            "    \"ELEMENT\" \"" + UDT_SCHEMA + "\".\"RAWS\" NOT NULL ENABLE \n" +
            "   )";
    protected static final String TAB_STORAGE2 = "CREATE TABLE %s.%s (\n" +
            "    \"ELMNO\" INTEGER NOT NULL ENABLE,\n" +
            "    \"XLOW\" BINARY_DOUBLE NOT NULL ENABLE,\n" +
            "    \"YLOW\" BINARY_DOUBLE NOT NULL ENABLE,\n" +
            "    \"XHIGH\" BINARY_DOUBLE NOT NULL ENABLE,\n" +
            "    \"YHIGH\" BINARY_DOUBLE NOT NULL ENABLE,\n" +
            "    \"EXTENTS\" MDSYS.SDO_GEOMETRY, \n" +
            "    \"PROPS\" INTEGER NOT NULL ENABLE,\n" +
            "    \"ID\" " + UDT_SCHEMA + ".OFMID NOT NULL ENABLE,\n" +
            "    \"LAYERID\" NUMBER(5) NOT NULL ENABLE,\n" +
            "    \"ELEMENT\" \"" + UDT_SCHEMA + "\".\"RAWS\" NOT NULL ENABLE \n" +
            "   )";
    /**
     * Trigger
     */
    protected static final String TRG_SPACENODE = "CREATE OR REPLACE TRIGGER \"%s\".\"%s\"\n"
            + "    AFTER DELETE OR INSERT OR UPDATE ON \"%s\".\"%s\"\n" + "    BEGIN\n"
            + "        UPDATE SPACENODES SET LASTUPDATE = SYSDATE\n" + "        WHERE SNID = \"%d\";\n"
            + "    END;";
    protected static final String TRG_ELMINDEX =
            "CREATE OR REPLACE TRIGGER \"%s\".\"%s\"\n"
                    + "    AFTER INSERT OR UPDATE OR DELETE ON \"%s\".\"%s\"\n"
                    + "    REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW\n"
                    + "    BEGIN\n"
                    + "        IF INSERTING THEN\n"
                    + "            INSERT INTO \"%s\".\"%s\" (ELMNO, TYPE, XLOW, YLOW, XHIGH, YHIGH,\n"
                    + "                UFID, FSC, COMPID, OCCID, SPACENAME)\n"
                    + "            VALUES (SD$ELEMENTNUMBER_SEQ.NEXTVAL, :new.ELMTYPE, :new.XLOW, :new.YLOW, :new.XHIGH, :new.YHIGH,\n"
                    + "                :new.UFID, :new.FSC, :new.COMPID, :new.OCCID, '%s');\n"
                    + "        ELSIF DELETING THEN\n"
                    + "            DELETE FROM \"%s\".\"%s\"\n"
                    + "            WHERE \"%s\".UFID = :old.UFID AND\n"
                    + "                \"%s\".FSC = :old.FSC AND\n"
                    + "                \"%s\".COMPID = :old.COMPID AND\n"
                    + "                \"%s\".OCCID = :old.OCCID;\n"
                    + "        ELSE\n" + "            UPDATE \"%s\"\n"
                    + "            SET XLOW = :new.XLOW, YLOW = :new.YLOW, XHIGH = :new.XHIGH, YHIGH = :new.YHIGH\n"
                    + "            WHERE FSC = :new.FSC AND UFID = :new.UFID AND COMPID = :new.COMPID AND OCCID = :new.OCCID;\n"
                    + "        END IF;\n" + "    END;";
    /**
     * copy connectivity to connectivity_webcheck sql
     */
    protected static final String TRUNCATE_CONNECTIVITY_WEBCHECK = "TRUNCATE TABLE  BASEDB.CONNECTIVITY_WEBCHECK";
    protected static final String CREATE_CONNECTIVITY_WEBCHECK = "CREATE TABLE BASEDB.CONNECTIVITY_WEBCHECK\n" +
            "( FSC      NUMBER(5) NOT NULL," +
            "  UFID     NUMBER(10) NOT NULL," +
            "  N1       NUMBER(10)," +
            "  N2       NUMBER(10)," +
            "  FDR1     NUMBER(5)," +
            "  FDR2     NUMBER(5)," +
            "  DIR      NUMBER(3)," +
            "  OHUG     NUMBER(3)," +
            "  OSTATUS  NUMBER(3)," +
            "  PHASE    NUMBER(3)," +
            "  X        NUMBER(10,3) NOT NULL," +
            "  Y        NUMBER(10,3) NOT NULL" +
            ")\n" +
            "TABLESPACE BASE_DATA PCTUSED 40 PCTFREE 10 INITRANS 1 MAXTRANS 255\n" +
            "STORAGE    (INITIAL 19120K MINEXTENTS 1 MAXEXTENTS 2147483645 \n" +
            "PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT )\n" +
            "LOGGING NOCOMPRESS NOCACHE NOPARALLEL MONITORING;";
     protected static final String COPY_CONNECTIVITY_TO_WEBCHECK = "INSERT /*+ APPEND */ INTO BASEDB.CONNECTIVITY_WEBCHECK\n" +
             "(FSC, UFID, N1, N2, FDR1, FDR2, DIR, OHUG,OSTATUS, PHASE, X, Y)\n" +
             "SELECT FSC, UFID, N1, N2, FDR1, FDR2, DIR, OHUG, OSTATUS, PHASE, X, Y FROM BASEDB.CONNECTIVITY ";
    /**
     *
     */
    protected static final String TAB_ELEMENTSET_PREFIX = "ELMSET_";
    protected static final String STMT_CLEARCYCLEBIN = "PURGE RECYCLEBIN";
    protected static final String SMTM_GRANTOBJECTTYPE = "GRANT EXECUTE ANY TYPE TO \"" + UDT_SCHEMA + "\"";
    protected static final long TIMEOUT = Long.MAX_VALUE;
    /**
     * Encoding of URL path.
     */
    protected static final String ENCODING = "UTF-8";
    private String _oracleHost;
    private String _oracleInstance;
    private String _oraclePort;
    protected String _dataPath;
    private OracleConnection oracleConnection = null;
    protected Properties properties;
    protected boolean _elementLogging;
    public static String getCurrentURL(String oracleHost, String oraclePort, String oracleInstance)
    {
        StringBuilder builder = new StringBuilder();
        builder.append(ORACLE_URL);
        builder.append(oracleHost);
        builder.append(":");
        builder.append(oraclePort);
        builder.append(":");
        builder.append(oracleInstance);
        return builder.toString();
    }
    public void setLogin(String userName, String password)
    {
        properties.put(PROPUsrKey, userName);
        properties.put(PROPPassKey, password);
    }
    public void setShapeData(String dataPath)
    {
        _dataPath = dataPath;
    }
    public OracleConnection getOracleConnection()
    {
        try
        {
            if (oracleConnection == null)
            {
                oracleConnection = (OracleConnection) DriverManager.getConnection(
                        getCurrentURL(_oracleHost, _oraclePort, _oracleInstance),
                        properties);
            }
            return oracleConnection;
        } catch (SQLException e)
        {
            OracleConvertJobContext.logger.warn(e.getMessage(), e);
        }
        oracleConnection = null;
        return null;
    }
    public void closeConnection()
    {
        try
        {
            if (oracleConnection != null)
            {
                oracleConnection.close();
                oracleConnection = null;
            }
        } catch (SQLException e)
        {
            OracleConvertJobContext.logger.warn(e.getMessage(), e);
        }
    }
    public void setConnectionInfo(String oracleHost, String oraclePort, String oracleInstance)
    {
        _oracleHost = oracleHost;
        _oracleInstance = oracleInstance;
        _oraclePort = oraclePort;
    }
    public String getDataPath()
    {
        return _dataPath;
    }
    public String getOracleHost()
    {
        return _oracleHost;
    }
    public String getOracleInstance()
    {
        return _oracleInstance;
    }
    public String getOraclePort()
    {
        return _oraclePort;
    }
    public boolean getElementLogging()
    {
        return _elementLogging;
    }
    public void setElementLogging(boolean elementLogging)
    {
        _elementLogging = elementLogging;
    }
    public abstract void startTransaction();
    public abstract void commitTransaction();
    public abstract void rollbackTransaction();
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/DummyFeatureConvertJobContext.java
New file
@@ -0,0 +1,297 @@
package com.ximple.eofms.jobs;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.io.IOException;
import java.nio.charset.Charset;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.transaction.util.LoggerFacade;
import org.apache.commons.transaction.util.CommonsLoggingLogger;
import org.apache.commons.transaction.memory.PessimisticMapWrapper;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import org.geotools.feature.Feature;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.geotools.feature.FeatureType;
import org.geotools.feature.SimpleFeature;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.indexed.IndexedShapefileDataStore;
import org.xml.sax.SAXException;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.filter.ElementDispatcher;
import com.ximple.eofms.filter.AbstractFLinkageDispatchableFilter;
import com.ximple.eofms.filter.ElementDispatchableFilter;
import com.ximple.eofms.filter.TypeCompIdDispatchableFilter;
import com.ximple.eofms.filter.TypeCompLevelIdDispatchableFilter;
import com.ximple.eofms.filter.TypeIdDispatchableFilter;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.ComplexElement;
import com.ximple.io.dgn7.UserAttributeData;
public class DummyFeatureConvertJobContext extends AbstractDgnFileJobContext
{
    static final Log logger = LogFactory.getLog(DummyFeatureConvertJobContext.class);
    static final LoggerFacade sLogger = new CommonsLoggingLogger(logger);
    static final GeometryFactory geometryFactory = new GeometryFactory();
    static final String SHPOUTPATH = "shpout";
    private String dataOut = null;
    private HashMap<String, ArrayList<Feature>> featuresContext = new HashMap<String, ArrayList<Feature>>();
    private HashMap<String, FeatureWriter> featuresWriterContext = new HashMap<String, FeatureWriter>();
    private PessimisticMapWrapper txFeaturesContext;
    private ElementDispatcher elementDispatcher;
    private String _filterConfig;
    public DummyFeatureConvertJobContext(String dataPath, String filterConfig)
    {
        super(dataPath);
        txFeaturesContext = new PessimisticMapWrapper(featuresContext, sLogger);
        _filterConfig = filterConfig;
        elementDispatcher = createElementDispatcher();
    }
    private ElementDispatcher createElementDispatcher()
    {
        try
        {
            URL rulesURL = ElementDispatcher.class.getResource("ElementDispatcherRules.xml");
            assert rulesURL != null;
            Digester digester = DigesterLoader.createDigester(rulesURL);
            URL filterURL = null;
            if (_filterConfig != null)
            {
                File config = new File(_filterConfig);
                if (config.exists())
                {
                    filterURL = config.toURI().toURL();
                }
            }
            if (filterURL == null)
            {
                // config = new File("conf/DefaultConvertShpFilter.xml");
                filterURL = this.getClass().getResource("/conf/DefaultConvertShpFilter.xml");
                // filterURL = this.getClass().getResource("/conf/ConvertShpFilterForLevel.xml");
            }
            assert filterURL != null;
            return (ElementDispatcher) digester.parse(filterURL);
        } catch (UnsupportedEncodingException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        } catch (MalformedURLException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        } catch (IOException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        } catch (SAXException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    public void putFeatureCollection(Element element) throws IllegalAttributeException, SchemaException
    {
        assert elementDispatcher != null;
        if (element == null)
        {
            logger.warn("Unknown Element:" + null);
            return;
        }
        // §PÂ_¬O§_²Å©M±ø¥ó
        Feature feature = elementDispatcher.execute(element);
        if (feature == null)
        {
            FrammeAttributeData linkage =
                    AbstractFLinkageDispatchableFilter.getFeatureLinkage(element);
            logger.warn("Unknown Element:" + element.getElementType().toString() +
                    ":type=" + element.getType() + ":lv=" + element.getLevelIndex() + ":id=" +
                    (linkage == null ? "NULL" : (linkage.getFsc() + "|" + linkage.getComponentID())));
            if (element instanceof ComplexElement)
            {
                ComplexElement complex = (ComplexElement) element;
                logger.warn("----Complex Element size=" + complex.size());
            }
            return;
        }
        if (!txFeaturesContext.containsKey(feature.getFeatureType()))
        {
            txFeaturesContext.put(feature.getFeatureType(), new ArrayList());
        }
        ArrayList arrayList = (ArrayList) txFeaturesContext.get(feature.getFeatureType());
        arrayList.add(feature);
    }
    public void startTransaction()
    {
        assert elementDispatcher != null;
        for (ElementDispatchableFilter filter : elementDispatcher.getRules())
        {
            if (filter instanceof TypeCompIdDispatchableFilter)
            {
                ((TypeCompIdDispatchableFilter) filter).getCreateStrategy();
            } else if (filter instanceof TypeCompLevelIdDispatchableFilter)
            {
                ((TypeCompIdDispatchableFilter) filter).getCreateStrategy();
            } else if(filter instanceof TypeIdDispatchableFilter)
            {
                ((TypeCompIdDispatchableFilter) filter).getCreateStrategy();
            }
        }
    }
    public void commitTransaction()
    {
        if (!txFeaturesContext.isEmpty())
        {
            logger.debug("Transaction size = " + txFeaturesContext.size());
            //txFeaturesContext.commitTransaction();
        } else
        {
            logger.debug("Transaction is empty.");
        }
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
    }
    public void rollbackTransaction()
    {
        //txFeaturesContext.rollbackTransaction();
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
    }
    private void updateDataStore()
    {
        Iterator it = featuresContext.keySet().iterator();
        try
        {
            while (it.hasNext())
            {
                FeatureType featureType = (FeatureType) it.next();
                File sfile = new File(getDataOutPath() + File.separator + featureType.getTypeName());
                logger.debug("Begin Save shapefile:" + sfile.toURI());
                FeatureWriter writer;
                if (featuresWriterContext.containsKey(featureType.getTypeName()))
                {
                    writer = featuresWriterContext.get(featureType.getTypeName());
                } else
                {
                    // ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL());
                    /*
                    ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL(),
                            true, Charset.forName("UTF-8"));
                    */
                    if (!sfile.exists())
                    {
                        ShapefileDataStore shapefileDataStore = new IndexedShapefileDataStore(sfile.toURI().toURL(),
                                null, true, true, IndexedShapefileDataStore.TREE_QIX, Charset.forName("UTF-8"));
                        shapefileDataStore.createSchema(featureType);
                        writer = shapefileDataStore.getFeatureWriter(featureType.getTypeName(),
                                Transaction.AUTO_COMMIT);
                    } else {
                        ShapefileDataStore shapefileDataStore = new IndexedShapefileDataStore(sfile.toURI().toURL(),
                                null, true, true, IndexedShapefileDataStore.TREE_QIX, Charset.forName("UTF-8"));
                        writer = shapefileDataStore.getFeatureWriterAppend(featureType.getTypeName(),
                                Transaction.AUTO_COMMIT);
                    }
                    featuresWriterContext.put(featureType.getTypeName(), writer);
                }
                ArrayList<Feature> features = featuresContext.get(featureType);
                Iterator itFeature = features.iterator();
                while (itFeature.hasNext())
                {
                    Feature feature = (Feature) itFeature.next();
                    ((SimpleFeature) writer.next()).setAttributes(feature.getAttributes(null));
                }
                //writer.close();
                logger.debug("End Save shapefile:" + sfile.toURI());
            }
            featuresContext.clear();
        } catch (MalformedURLException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IllegalAttributeException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IOException e)
        {
            logger.error(e.getMessage(), e);
        }
    }
    public String getDataOutPath()
    {
        if (dataOut == null)
        {
            File outPath = new File(getDataPath(), SHPOUTPATH);
            if (!outPath.exists())
            {
                outPath.mkdir();
            } else if (!outPath.isDirectory())
            {
                outPath.mkdir();
            }
            dataOut = outPath.toString();
        }
        return dataOut;
    }
    public void closeFeatureWriter() throws IOException {
        for (FeatureWriter featureWriter : this.featuresWriterContext.values())
        {
            featureWriter.close();
        }
        this.featuresWriterContext.clear();
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/FeatureDgnConvertJobContext.java
New file
@@ -0,0 +1,280 @@
package com.ximple.eofms.jobs;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.transaction.memory.PessimisticMapWrapper;
import org.apache.commons.transaction.util.CommonsLoggingLogger;
import org.apache.commons.transaction.util.LoggerFacade;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.indexed.IndexedShapefileDataStore;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.geotools.feature.SimpleFeature;
import org.xml.sax.SAXException;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.filter.AbstractFLinkageDispatchableFilter;
import com.ximple.eofms.filter.ElementDispatcher;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.UserAttributeData;
import com.ximple.io.dgn7.ComplexElement;
public class FeatureDgnConvertJobContext extends AbstractDgnFileJobContext
{
    static final Log logger = LogFactory.getLog(FeatureDgnConvertJobContext.class);
    static final LoggerFacade sLogger = new CommonsLoggingLogger(logger);
    static final GeometryFactory geometryFactory = new GeometryFactory();
    static final String SHPOUTPATH = "shpout";
    private String dataOut = null;
    private HashMap<String, ArrayList<Feature>> featuresContext = new HashMap<String, ArrayList<Feature>>();
    private HashMap<String, FeatureWriter> featuresWriterContext = new HashMap<String, FeatureWriter>();
    private PessimisticMapWrapper txFeaturesContext;
    private ElementDispatcher elementDispatcher;
    private String _filterConfig;
    public FeatureDgnConvertJobContext(String dataPath, String filterConfig)
    {
        super(dataPath);
        txFeaturesContext = new PessimisticMapWrapper(featuresContext, sLogger);
        _filterConfig = filterConfig;
        elementDispatcher = createElementDispatcher();
    }
    private ElementDispatcher createElementDispatcher()
    {
        try
        {
            URL rulesURL = ElementDispatcher.class.getResource("ElementDispatcherRules.xml");
            assert rulesURL != null;
            Digester digester = DigesterLoader.createDigester(rulesURL);
            URL filterURL = null;
            if (_filterConfig != null)
            {
                File config = new File(_filterConfig);
                if (config.exists())
                {
                    filterURL = config.toURI().toURL();
                }
            }
            if (filterURL == null)
            {
                // config = new File("conf/DefaultConvertShpFilter.xml");
                filterURL = this.getClass().getResource("/conf/DefaultConvertShpFilter.xml");
                // filterURL = this.getClass().getResource("/conf/ConvertShpFilterForLevel.xml");
            }
            assert filterURL != null;
            return (ElementDispatcher) digester.parse(filterURL);
        } catch (UnsupportedEncodingException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        } catch (MalformedURLException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        } catch (IOException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        } catch (SAXException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    public void putFeatureCollection(Element element) throws IllegalAttributeException, SchemaException
    {
        assert elementDispatcher != null;
        if (element == null)
        {
            logger.warn("Unknown Element:" + null);
            return;
        }
        // §PÂ_¬O§_²Å©M±ø¥ó
        Feature feature = elementDispatcher.execute(element);
        if (feature == null)
        {
            FrammeAttributeData linkage =
                    AbstractFLinkageDispatchableFilter.getFeatureLinkage(element);
            logger.warn("Unknown Element:" + element.getElementType().toString() +
                    ":type=" + element.getType() + ":lv=" + element.getLevelIndex() + ":id=" +
                    (linkage == null ? "NULL" : (linkage.getFsc() + "|" + linkage.getComponentID())));
            if (element instanceof ComplexElement)
            {
                ComplexElement complex = (ComplexElement) element;
                logger.warn("----Complex Element size=" + complex.size());
            }
            return;
        }
        if (!txFeaturesContext.containsKey(feature.getFeatureType()))
        {
            txFeaturesContext.put(feature.getFeatureType(), new ArrayList());
        }
        ArrayList arrayList = (ArrayList) txFeaturesContext.get(feature.getFeatureType());
        arrayList.add(feature);
    }
    public void startTransaction()
    {
    }
    public void commitTransaction()
    {
        if (!txFeaturesContext.isEmpty())
        {
            logger.debug("Transaction size = " + txFeaturesContext.size());
            //txFeaturesContext.commitTransaction();
        } else
        {
            logger.debug("Transaction is empty.");
        }
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
    }
    public void rollbackTransaction()
    {
        //txFeaturesContext.rollbackTransaction();
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
    }
    private void updateDataStore()
    {
        Iterator it = featuresContext.keySet().iterator();
        try
        {
            while (it.hasNext())
            {
                FeatureType featureType = (FeatureType) it.next();
                File sfile = new File(getDataOutPath() + File.separator + featureType.getTypeName());
                logger.debug("Begin Save shapefile:" + sfile.toURI());
                FeatureWriter writer;
                if (featuresWriterContext.containsKey(featureType.getTypeName()))
                {
                    writer = featuresWriterContext.get(featureType.getTypeName());
                } else
                {
                    // ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL());
                    /*
                    ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL(),
                            true, Charset.forName("UTF-8"));
                    */
                    if (!sfile.exists())
                    {
                        ShapefileDataStore shapefileDataStore = new IndexedShapefileDataStore(sfile.toURI().toURL(),
                                null, true, true, IndexedShapefileDataStore.TREE_QIX, Charset.forName("UTF-8"));
                        shapefileDataStore.createSchema(featureType);
                        writer = shapefileDataStore.getFeatureWriter(featureType.getTypeName(),
                                Transaction.AUTO_COMMIT);
                    } else {
                        ShapefileDataStore shapefileDataStore = new IndexedShapefileDataStore(sfile.toURI().toURL(),
                                null, true, true, IndexedShapefileDataStore.TREE_QIX, Charset.forName("UTF-8"));
                        writer = shapefileDataStore.getFeatureWriterAppend(featureType.getTypeName(),
                                Transaction.AUTO_COMMIT);
                    }
                    featuresWriterContext.put(featureType.getTypeName(), writer);
                }
                ArrayList<Feature> features = featuresContext.get(featureType);
                Iterator itFeature = features.iterator();
                while (itFeature.hasNext())
                {
                    Feature feature = (Feature) itFeature.next();
                    ((SimpleFeature) writer.next()).setAttributes(feature.getAttributes(null));
                }
                //writer.close();
                logger.debug("End Save shapefile:" + sfile.toURI());
            }
            featuresContext.clear();
        } catch (MalformedURLException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IllegalAttributeException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IOException e)
        {
            logger.error(e.getMessage(), e);
        }
    }
    public String getDataOutPath()
    {
        if (dataOut == null)
        {
            File outPath = new File(getDataPath(), SHPOUTPATH);
            if (!outPath.exists())
            {
                outPath.mkdir();
            } else if (!outPath.isDirectory())
            {
                outPath.mkdir();
            }
            dataOut = outPath.toString();
        }
        return dataOut;
    }
    public void closeFeatureWriter() throws IOException {
        for (FeatureWriter featureWriter : this.featuresWriterContext.values())
        {
            featureWriter.close();
        }
        this.featuresWriterContext.clear();
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/GeneralDgnConvertJobContext.java
New file
@@ -0,0 +1,554 @@
package com.ximple.eofms.jobs;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
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.memory.PessimisticMapWrapper;
import org.apache.commons.transaction.util.CommonsLoggingLogger;
import org.apache.commons.transaction.util.LoggerFacade;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.indexed.IndexedShapefileDataStore;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.geotools.feature.SimpleFeature;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.util.DefaultColorTable;
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 GeneralDgnConvertJobContext extends AbstractDgnFileJobContext
{
    static final Log logger = LogFactory.getLog(GeneralDgnConvertJobContext.class);
    static final LoggerFacade sLogger = new CommonsLoggingLogger(logger);
    static final GeometryFactory geometryFactory = new GeometryFactory();
    static final String SHPOUTPATH = "shpout";
    private String dataOut = null;
    private HashMap<String, ArrayList<Feature>> featuresContext = new HashMap<String, ArrayList<Feature>>();
    private HashMap<String, FeatureWriter> featuresWriterContext = new HashMap<String, FeatureWriter>();
    private PessimisticMapWrapper txFeaturesContext;
    private TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>();
    private TreeMap<String, FeatureType> featureTypes = new TreeMap<String, FeatureType>();
    private TWD97GeometryConverterDecorator convertDecorator = null;
    private String featureBaseName = null;
    public GeneralDgnConvertJobContext(String dataPath)
    {
        super(dataPath);
        txFeaturesContext = new PessimisticMapWrapper(featuresContext, sLogger);
        convertDecorator = new TWD97GeometryConverterDecorator();
    }
    public void putFeatureCollection(Element element) throws IllegalAttributeException, SchemaException
    {
        FeatureType ft = lookupFeatureType(element);
        if (ft != null)
        {
            Feature feature = createFeature(ft, element);
            if (feature == null)
            {
                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<Feature>());
            }
            ArrayList<Feature> arrayList = (ArrayList<Feature>) txFeaturesContext.get(feature.getFeatureType());
            arrayList.add(feature);
        } else
        {
            logger.info("Unknown Element :" + element.getType() + ", lv=" + element.getLevelIndex());
        }
    }
    public void startTransaction()
    {
    }
    public void commitTransaction()
    {
        if (!txFeaturesContext.isEmpty())
        {
            logger.debug("Transaction size = " + txFeaturesContext.size());
            //txFeaturesContext.commitTransaction();
        } else
        {
            logger.debug("Transaction is empty.");
        }
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
    }
    public void rollbackTransaction()
    {
        //txFeaturesContext.rollbackTransaction();
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
    }
    private void updateDataStore()
    {
        Iterator it = featuresContext.keySet().iterator();
        try
        {
            while (it.hasNext())
            {
                FeatureType featureType = (FeatureType) it.next();
                File sfile = new File(getDataOutPath() + File.separator + featureType.getTypeName());
                logger.debug("Begin Save shapefile:" + sfile.toURI());
                FeatureWriter writer;
                if (featuresWriterContext.containsKey(featureType.getTypeName()))
                {
                    writer = featuresWriterContext.get(featureType.getTypeName());
                } else
                {
                    // ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL());
                    /*
                    ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL(),
                            true, Charset.forName("UTF-8"));
                    */
                    if (!sfile.exists())
                    {
                        ShapefileDataStore shapefileDataStore = new IndexedShapefileDataStore(sfile.toURI().toURL(),
                                null, true, true, IndexedShapefileDataStore.TREE_QIX, Charset.forName("UTF-8"));
                        shapefileDataStore.createSchema(featureType);
                        writer = shapefileDataStore.getFeatureWriter(featureType.getTypeName(),
                                Transaction.AUTO_COMMIT);
                    } else
                    {
                        ShapefileDataStore shapefileDataStore = new IndexedShapefileDataStore(sfile.toURI().toURL(),
                                null, true, true, IndexedShapefileDataStore.TREE_QIX, Charset.forName("UTF-8"));
                        writer = shapefileDataStore.getFeatureWriterAppend(featureType.getTypeName(),
                                Transaction.AUTO_COMMIT);
                    }
                    featuresWriterContext.put(featureType.getTypeName(), writer);
                }
                ArrayList<Feature> features = featuresContext.get(featureType);
                Iterator itFeature = features.iterator();
                while (itFeature.hasNext())
                {
                    Feature feature = (Feature) itFeature.next();
                    ((SimpleFeature) writer.next()).setAttributes(feature.getAttributes(null));
                }
                //writer.close();
                logger.debug("End Save shapefile:" + sfile.toURI());
            }
            featuresContext.clear();
        } catch (MalformedURLException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IllegalAttributeException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IOException e)
        {
            logger.error(e.getMessage(), e);
        }
    }
    public String getDataOutPath()
    {
        if (dataOut == null)
        {
            File outPath = new File(getDataPath(), SHPOUTPATH);
            if (!outPath.exists())
            {
                outPath.mkdir();
            } else if (!outPath.isDirectory())
            {
                outPath.mkdir();
            }
            dataOut = outPath.toString();
        }
        return dataOut;
    }
    public void closeFeatureWriter() throws IOException
    {
        for (FeatureWriter featureWriter : this.featuresWriterContext.values())
        {
            featureWriter.close();
        }
        this.featuresWriterContext.clear();
    }
    public FeatureType createPointFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("FONT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("JUST", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("HEIGHT", Double.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("WIDTH", Double.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("ANGLE", Double.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("CONTEXT", String.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public FeatureType createLineFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public FeatureType createArcFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public FeatureType createEllipseFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilder.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilders.put(featureName, typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        if (element instanceof TextElement)
        {
            TextElement textElement = (TextElement) element;
            convertDecorator.setConverter(textElement);
            Geometry geom = convertDecorator.toGeometry(geometryFactory);
            double angle = textElement.getRotationAngle();
            String content = textElement.getText();
            angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue();
            if (geom != null)
            {
                return featureType.create(new Object[]{
                        geom,
                        colorTable.getColorCode(textElement.getColorIndex()),
                        textElement.getFontIndex(),
                        textElement.getJustification(),
                        textElement.getTextHeight(),
                        textElement.getTextWidth(),
                        angle,
                        content
                });
            } 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();
            StringBuffer sb = new StringBuffer();
            for (String text : texts)
            {
                if (sb.length() != 0)
                    sb.append("\n");
                sb.append(text);
            }
            if (geom != null)
            {
                return featureType.create(new Object[]{
                        geom,
                        colorTable.getColorCode(textNodeElement.getColorIndex()),
                        textNodeElement.getFontIndex(),
                        textNodeElement.getJustification(),
                        textNodeElement.getTextNodeHeight(),
                        textNodeElement.getTextNodeLength(),
                        angle,
                        sb.toString()
                });
            } 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 featureType.create(new Object[]{
                        geom,
                        colorTable.getColorCode(shapeElement.getColorIndex()),
                        shapeElement.getWeight(),
                        shapeElement.getLineStyle()
                });
            } 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 featureType.create(new Object[]{
                        geom,
                        colorTable.getColorCode(linestring.getColorIndex()),
                        linestring.getWeight(),
                        linestring.getLineStyle()
                });
            return null;
        } else if (element instanceof LineElement)
        {
            LineElement line = (LineElement) element;
            convertDecorator.setConverter(line);
            Geometry geom = convertDecorator.toGeometry(geometryFactory);
            if (geom != null)
                return featureType.create(new Object[]{
                        geom,
                        colorTable.getColorCode(line.getColorIndex()),
                        line.getWeight(),
                        line.getLineStyle()
                });
            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 featureType.create(new Object[]{
                        geom,
                        colorTable.getColorCode(arcElement.getColorIndex()),
                        arcElement.getWeight(),
                        arcElement.getLineStyle()
                });
            return null;
        } else if (element instanceof EllipseElement)
        {
            EllipseElement arcElement = (EllipseElement) element;
            convertDecorator.setConverter(arcElement);
            Geometry geom = convertDecorator.toGeometry(geometryFactory);
            if (geom != null)
                return featureType.create(new Object[]{
                        geom,
                        colorTable.getColorCode(arcElement.getColorIndex()),
                        arcElement.getWeight(),
                        arcElement.getLineStyle()
                });
            return null;
        } else if (element instanceof ComplexChainElement)
        {
            ComplexChainElement complexChainElement = (ComplexChainElement) element;
            convertDecorator.setConverter(complexChainElement);
            Geometry geom = convertDecorator.toGeometry(geometryFactory);
            if (geom != null)
                return featureType.create(new Object[]{
                        geom,
                        colorTable.getColorCode(complexChainElement.getColorIndex()),
                        complexChainElement.getWeight(),
                        complexChainElement.getLineStyle()
                });
            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 FeatureType lookupFeatureType(Element element) throws SchemaException, IllegalAttributeException
    {
        String typeName;
        if (element instanceof TextElement)
        {
            typeName = getFeatureBaseName() + "P";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createPointFeatureElement(typeName));
            }
            return featureTypes.get(typeName);
        } else if (element instanceof TextNodeElement)
        {
            typeName = getFeatureBaseName() + "P";
            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";
                if (!featureTypes.containsKey(typeName))
                {
                    featureTypes.put(typeName, createLineFeatureElement(typeName));
                }
                return featureTypes.get(typeName);
            } else
            {
                typeName = getFeatureBaseName() + "L";
                if (!featureTypes.containsKey(typeName))
                {
                    featureTypes.put(typeName, createLineFeatureElement(typeName));
                }
                return featureTypes.get(typeName);
            }
        } else if (element instanceof LineElement)
        {
            typeName = getFeatureBaseName() + "L";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createLineFeatureElement(typeName));
            }
            return featureTypes.get(typeName);
        } else if (element instanceof ComplexChainElement)
        {
            typeName = getFeatureBaseName() + "L";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createLineFeatureElement(typeName));
            }
            return featureTypes.get(typeName);
        } else if (element instanceof ArcElement)
        {
            typeName = getFeatureBaseName() + "A";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createArcFeatureElement(typeName));
            }
            return featureTypes.get(typeName);
        } else if (element instanceof EllipseElement)
        {
            typeName = getFeatureBaseName() + "R";
            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<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/IndexDgnConvertJobContext.java
New file
@@ -0,0 +1,355 @@
package com.ximple.eofms.jobs;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.transaction.memory.PessimisticMapWrapper;
import org.apache.commons.transaction.util.CommonsLoggingLogger;
import org.apache.commons.transaction.util.LoggerFacade;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.indexed.IndexedShapefileDataStore;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.geotools.feature.SimpleFeature;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.ximple.eofms.util.DefaultColorTable;
import com.ximple.eofms.util.TPCLIDConverter;
import com.ximple.eofms.util.TWDDatumConverter;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.TextElement;
import com.ximple.io.dgn7.UserAttributeData;
public class IndexDgnConvertJobContext extends AbstractDgnFileJobContext
{
    static final Log logger = LogFactory.getLog(IndexDgnConvertJobContext.class);
    static final LoggerFacade sLogger = new CommonsLoggingLogger(logger);
    static final GeometryFactory geometryFactory = new GeometryFactory();
    TWD97GeometryConverterDecorator convertDecorator = new TWD97GeometryConverterDecorator();
    static final String SHPOUTPATH = "shpout";
    private String dataOut = null;
    private HashMap<String, ArrayList<Feature>> featuresContext = new HashMap<String, ArrayList<Feature>>();
    private HashMap<String, FeatureWriter> featuresWriterContext = new HashMap<String, FeatureWriter>();
    private PessimisticMapWrapper txFeaturesContext;
    private FeatureTypeBuilder typeBuilderPnt = null;
    private FeatureTypeBuilder typeBuilderRect = null;
    private FeatureType featureType = null;
    private FeatureType featureType2 = null;
    public IndexDgnConvertJobContext(String dataPath)
    {
        super(dataPath);
        txFeaturesContext = new PessimisticMapWrapper(featuresContext, sLogger);
    }
    public void putFeatureCollection(Element element) throws IllegalAttributeException, SchemaException
    {
        if (!(element instanceof TextElement))
        {
            return;
        }
        Feature feature = createFeature((TextElement) element);
        if (feature == null)
        {
            logger.info("cannot craete feature." + element.toString() + "'" +
                    ((TextElement) element).getText() + "'");
            return;
        }
        if (!txFeaturesContext.containsKey(feature.getFeatureType()))
        {
            txFeaturesContext.put(feature.getFeatureType(), new ArrayList());
        }
        ArrayList arrayList = (ArrayList) txFeaturesContext.get(feature.getFeatureType());
        arrayList.add(feature);
        feature = createFeature2((TextElement) element);
        if (feature == null)
        {
            logger.info("cannot craete feature2." + element.toString() + "'" +
                    ((TextElement) element).getText() + "'");
            return;
        }
        if (!txFeaturesContext.containsKey(feature.getFeatureType()))
        {
            txFeaturesContext.put(feature.getFeatureType(), new ArrayList());
        }
        arrayList = (ArrayList) txFeaturesContext.get(feature.getFeatureType());
        arrayList.add(feature);
    }
    public void startTransaction()
    {
    }
    public void commitTransaction()
    {
        if (!txFeaturesContext.isEmpty())
        {
            logger.debug("Transaction size = " + txFeaturesContext.size());
            //txFeaturesContext.commitTransaction();
        } else
        {
            logger.debug("Transaction is empty.");
        }
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
    }
    public void rollbackTransaction()
    {
        //txFeaturesContext.rollbackTransaction();
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
    }
    private void updateDataStore()
    {
        Iterator it = featuresContext.keySet().iterator();
        try
        {
            while (it.hasNext())
            {
                FeatureType featureType = (FeatureType) it.next();
                File sfile = new File(getDataOutPath() + File.separator + featureType.getTypeName());
                logger.debug("Begin Save shapefile:" + sfile.toURI());
                FeatureWriter writer;
                if (featuresWriterContext.containsKey(featureType.getTypeName()))
                {
                    writer = featuresWriterContext.get(featureType.getTypeName());
                } else
                {
                    /*
                    ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL(),
                            true, Charset.forName("UTF-8"));
                    */
                    ShapefileDataStore shapefileDataStore = new IndexedShapefileDataStore(sfile.toURI().toURL(),
                            null, true, true, IndexedShapefileDataStore.TREE_QIX, Charset.forName("UTF-8"));
                    shapefileDataStore.createSchema(featureType);
                    writer = shapefileDataStore.getFeatureWriter(featureType.getTypeName(), Transaction.AUTO_COMMIT);
                    featuresWriterContext.put(featureType.getTypeName(), writer);
                }
                ArrayList<Feature> features = featuresContext.get(featureType);
                for (Feature feature1 : features)
                {
                    ((SimpleFeature) writer.next()).setAttributes(feature1.getAttributes(null));
                }
                //writer.close();
                logger.debug("End Save shapefile:" + sfile.toURI());
            }
            featuresContext.clear();
        } catch (MalformedURLException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IllegalAttributeException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IOException e)
        {
            logger.error(e.getMessage(), e);
        }
    }
    public String getDataOutPath()
    {
        if (dataOut == null)
        {
            File outPath = new File(getDataPath(), SHPOUTPATH);
            if (!outPath.exists())
            {
                outPath.mkdir();
            } else if (!outPath.isDirectory())
            {
                outPath.mkdir();
            }
            dataOut = outPath.toString();
        }
        return dataOut;
    }
    public void closeFeatureWriter() throws IOException
    {
        for (FeatureWriter featureWriter : this.featuresWriterContext.values())
        {
            featureWriter.close();
        }
        this.featuresWriterContext.clear();
    }
    public FeatureType createFeatureElement(String featureName) throws SchemaException
    {
        if (typeBuilderRect == null)
        {
            typeBuilderRect = FeatureTypeBuilder.newInstance(featureName);
            typeBuilderRect.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilderRect.addType(AttributeTypeFactory.newAttributeType("X1", Double.class));
            typeBuilderRect.addType(AttributeTypeFactory.newAttributeType("Y1", Double.class));
            typeBuilderRect.addType(AttributeTypeFactory.newAttributeType("X2", Double.class));
            typeBuilderRect.addType(AttributeTypeFactory.newAttributeType("Y2", Double.class));
            typeBuilderRect.addType(AttributeTypeFactory.newAttributeType("TPCID", String.class));
            typeBuilderRect.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilderRect.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilderRect.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
        }
        return typeBuilderRect.getFeatureType();
    }
    public FeatureType createFeatureElement2(String featureName) throws SchemaException
    {
        if (typeBuilderPnt == null)
        {
            typeBuilderPnt = FeatureTypeBuilder.newInstance(featureName);
            typeBuilderPnt.addType(AttributeTypeFactory.newAttributeType("GEOM", Geometry.class));
            typeBuilderPnt.addType(AttributeTypeFactory.newAttributeType("SYMCOLOR", String.class));
            typeBuilderPnt.addType(AttributeTypeFactory.newAttributeType("SYMWEIGHT", Integer.class));
            typeBuilderPnt.addType(AttributeTypeFactory.newAttributeType("SYMSTYLE", Integer.class));
            typeBuilderPnt.addType(AttributeTypeFactory.newAttributeType("JUST", Integer.class));
            typeBuilderPnt.addType(AttributeTypeFactory.newAttributeType("HEIGHT", Double.class));
            typeBuilderPnt.addType(AttributeTypeFactory.newAttributeType("WIDTH", Double.class));
            typeBuilderPnt.addType(AttributeTypeFactory.newAttributeType("ANGLE", Double.class));
            typeBuilderPnt.addType(AttributeTypeFactory.newAttributeType("TPCID", String.class));
        }
        return typeBuilderPnt.getFeatureType();
    }
    public Feature createFeature(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        if (element instanceof TextElement)
        {
            TextElement textElement = (TextElement) element;
            String tpclid = textElement.getText();
            Envelope extent = TPCLIDConverter.convertTpclIdToEnvelope(tpclid);
            Geometry geom = geometryFactory.createLinearRing(new Coordinate[]
                    {
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMinX(), extent.getMinY())),
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMaxX(), extent.getMinY())),
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMaxX(), extent.getMaxY())),
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMinX(), extent.getMaxY())),
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMinX(), extent.getMinY())),
                    });
            return featureType.create(new Object[]{
                    geom,
                    extent.getMinX(),
                    extent.getMinY(),
                    extent.getMaxX(),
                    extent.getMaxY(),
                    tpclid,
                    colorTable.getColorCode(textElement.getColorIndex()),
                    textElement.getWeight(),
                    textElement.getLineStyle()
            });
        }
        return null;
    }
    public Feature createFeature2(FeatureType featureType, Element element) throws IllegalAttributeException
    {
        DefaultColorTable colorTable = (DefaultColorTable) DefaultColorTable.getInstance();
        if (element instanceof TextElement)
        {
            TextElement txtElement = (TextElement) element;
            double angle = txtElement.getRotationAngle();
            angle = BigDecimal.valueOf(angle).setScale(3, RoundingMode.HALF_UP).doubleValue();
            convertDecorator.setConverter(txtElement);
            Feature feature = featureType.create(new Object[]{
                    convertDecorator.toGeometry(geometryFactory),
                    colorTable.getColorCode(txtElement.getColorIndex()),
                    txtElement.getWeight(),
                    txtElement.getLineStyle(),
                    txtElement.getJustification(),
                    txtElement.getTextHeight(),
                    txtElement.getTextWidth(),
                    angle,
                    txtElement.getText()
            });
            return feature;
        }
        return null;
    }
    private Feature createFeature(TextElement element) throws SchemaException, IllegalAttributeException
    {
        if (featureType == null)
        {
            String dgnname = getFilename().toLowerCase();
            int i = dgnname.lastIndexOf(".");
            if (i != -1)
            {
                dgnname = dgnname.substring(0, i);
            }
            featureType = createFeatureElement(dgnname);
        }
        return createFeature(featureType, element);
    }
    private Feature createFeature2(TextElement element) throws SchemaException, IllegalAttributeException
    {
        if (featureType2 == null)
        {
            String dgnname = getFilename().toLowerCase();
            int i = dgnname.lastIndexOf(".");
            if (i != -1)
            {
                dgnname = dgnname.substring(0, i);
            }
            dgnname = dgnname + "P";
            featureType2 = createFeatureElement2(dgnname);
        }
        return createFeature2(featureType2, element);
    }
    protected FrammeAttributeData getFeatureLinkage(Element element)
    {
        if (!element.hasUserAttributeData())
            return null;
        List<UserAttributeData> usrDatas = element.getUserAttributeData();
        for (UserAttributeData anUsrData : usrDatas)
        {
            if (anUsrData instanceof FrammeAttributeData)
            {
                return (FrammeAttributeData) anUsrData;
            }
        }
        return null;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertDgn2ShpJob.java
New file
@@ -0,0 +1,917 @@
package com.ximple.eofms.jobs;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Date;
import org.apache.commons.collections.OrderedMap;
import org.apache.commons.collections.OrderedMapIterator;
import org.apache.commons.collections.map.LinkedMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.vividsolutions.jts.geom.GeometryFactory;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleResultSet;
import oracle.sql.ARRAY;
import oracle.sql.BLOB;
import com.ximple.eofms.util.BinConverter;
import com.ximple.eofms.util.ByteArrayCompressor;
import com.ximple.eofms.util.StringUtils;
import com.ximple.io.dgn7.ComplexElement;
import com.ximple.io.dgn7.Dgn7fileException;
import com.ximple.io.dgn7.Dgn7fileReader;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.ElementType;
import com.ximple.io.dgn7.IElementHandler;
import com.ximple.io.dgn7.Lock;
import com.ximple.io.dgn7.TextElement;
import com.ximple.util.PrintfFormat;
/**
 *
 */
public class OracleConvertDgn2ShpJob extends AbstractOracleDatabaseJob
{
    final static Log logger = LogFactory.getLog(OracleConvertDgn2ShpJob.class);
    private static final int FETCHSIZE = 30;
    private static final int BATCHSIZE = 25;
    private static final int COMMITSIZE = 20;
    class Pair
    {
        Object first;
        Object second;
        public Pair(Object first, Object second)
        {
            this.first = first;
            this.second = second;
        }
    }
    GeometryFactory _geomFactory = new GeometryFactory();
    public Log getLogger()
    {
        return logger;
    }
    protected AbstractOracleJobContext prepareJobContext(String filterPath)
    {
        return new OracleConvertJobContext(filterPath);
    }
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
        // Every job has its own job detail
        JobDetail jobDetail = context.getJobDetail();
        // The name is defined in the job definition
        String jobName = jobDetail.getName();
        // Log the time the job started
        logger.info(jobName + " fired at " + new Date());
        extractJobConfiguration(jobDetail);
        try
        {
            logger.info("-- step:clearOutputDirectory --");
            clearOutputDirectory();
            boolean bFirst = true;
            if (checkConvertDB())
            {
                logger.info("-- step:convertOracleDB --");
                for (String orgSchema : _orgSchema)
                {
                    OracleConvertJobContext jobContext = (OracleConvertJobContext) prepareJobContext(_filterPath);
                    jobContext.setConnectionInfo(_oracleHost, _oraclePort, _oracleInstance);
                    jobContext.setLogin(_username, _password);
                    jobContext.setShapeData(_dataPath);
                    jobContext.setConvertDB(_convertDB);
                    jobContext.setConvertFile(_convertFile);
                    jobContext.setConvertElementIn(_convertElementIn);
                    jobContext.setElementLogging(checkElementLogging());
                    jobContext.setExecutionContext(context);
                    if (bFirst)
                        copyConnectivity(jobContext);
                    else
                        bFirst = false;
                    logger.info("----- start schema:" + orgSchema + " -----");
                    exetcuteConvert(jobContext, orgSchema, _dataPath);
                    //close all open filewriter instance
                    jobContext.closeFeatureWriter();
                }
            }
            if (checkConvertFile())
            {
                logger.info("-- step:convertIndexDesignFile --");
                convertIndexDesignFile(context);
                logger.info("-- step:convertOtherDesignFile --");
                convertOtherDesignFile(context);
            }
            if (checkConvertElementIn())
            {
                logger.info("-- step:convertFeatureDesignFile --");
                convertFeatureDesignFile(context);
            }
            if (checkCreateDummy())
            {
                logger.info("-- step:createDummyFeatureFile --");
                createDummyFeatureFile(context);
            }
        } catch (SQLException e)
        {
            logger.warn(e.getMessage(), e);
            throw new JobExecutionException("Database error. " + e.getMessage(), e);
        } catch (IOException ex)
        {
            logger.warn(ex.getMessage(), ex);
            throw new JobExecutionException("IO error. " + ex.getMessage(), ex);
        }
        logger.info(jobName + " end at " + new Date());
    }
    /**
     * Connectivity½Æ»s¤@­Óª©¥»¡A¦b¬d¸ß¹q¬y¤è¦V®É¥Î¨Ó¤ñ¹ïOMS¸ê®Æ®wªº¹q¾¹³s±µ©Ê(Connectivity)
     *
     * @param jobContext job context
     * @throws SQLException sql exception
     */
    private void copyConnectivity(OracleConvertJobContext jobContext) throws SQLException
    {
        OracleConnection connection = jobContext.getOracleConnection();
        Statement stmt = connection.createStatement();
        stmt.execute(OracleConvertJobContext.TRUNCATE_CONNECTIVITY_WEBCHECK);
        stmt.execute(OracleConvertJobContext.COPY_CONNECTIVITY_TO_WEBCHECK);
    }
    private void exetcuteConvert(OracleConvertJobContext jobContext,
                                 String querySchema, String dataPath) throws SQLException
    {
        int order = 0;
        OrderedMap map = getBlobStorageList(jobContext.getOracleConnection(), querySchema, "SD$SPACENODES"
                , null);
        logger.info("begin convert job:[" + map.size() + "]:testmode=" + _testMode);
        int total = map.size(); //spacenodes count
        int step = total / 100;
        int current = 0;
        //jobContext.startTransaction();
        jobContext.setCurrentSchema(querySchema);
        jobContext.getExecutionContext().put("ConvertDgn2ShpJobProgress", 0);
        for (OrderedMapIterator it = map.orderedMapIterator(); it.hasNext();)
        {
            it.next();
            Pair pair = (Pair) it.getValue();
            String tableSrc = (String) pair.first;
            logger.info("begin convert:[" + order + "]-" + tableSrc);
            queryIgsetElement(jobContext, querySchema, tableSrc);
            order++;
            if (_testMode)
            {
                if ((_testCount < 0) || (order >= _testCount))
                    break;
            }
            if ((order % COMMITSIZE) == 0)
            {
                // OracleConnection connection = jobContext.getOracleConnection();
                // connection.commitTransaction();
                jobContext.commitTransaction();
                //jobContext.startTransaction();
                System.gc();
            }
            int now = order % step;
            if (now != current)
            {
                current = now;
                jobContext.getExecutionContext().put("ConvertDgn2ShpJobProgress", current);
            }
        }
        jobContext.getExecutionContext().put("ConvertDgn2ShpJobProgress", 100);
        jobContext.commitTransaction();
        logger.info("end convert job:[" + order + "]");
        System.gc();
    }
    protected OrderedMap getBlobStorageList(OracleConnection connection, String schemaSrc, String tableSrc,
                                            OrderedMap orderedMap) throws SQLException
    {
        if (orderedMap == null)
            orderedMap = new LinkedMap(99);
        String fetchStmtFmt = "SELECT SNID, SPACETABLE FROM \"%s\".\"%s\"";
        PrintfFormat spf = new PrintfFormat(fetchStmtFmt);
        String fetchStmt = spf.sprintf(new Object[]{schemaSrc, tableSrc});
        Statement stmt = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        ResultSet rs = null;
        stmt.setFetchSize(FETCHSIZE);
        try
        {
            rs = stmt.executeQuery(fetchStmt);
            while (rs.next())
            {
                int size = rs.getMetaData().getColumnCount();
                Object[] values = new Object[size];
                for (int i = 0; i < size; i++)
                {
                    values[i] = rs.getObject(i + 1);
                }
                Integer key = ((BigDecimal) values[0]).intValue();
                String name = (String) values[1];
                Pair pair = (Pair) orderedMap.get(key);
                if (pair == null)
                    orderedMap.put(key, new Pair(name, null));
                else
                    pair.first = name;
            }
        } catch (SQLException e)
        {
            logger.error(e.toString(), e);
            logger.error("stmt=" + fetchStmt);
            throw e;
        } finally
        {
            if (rs != null) rs.close();
            stmt.close();
        }
        return orderedMap;
    }
    protected OrderedMap getRawFormatStorageList(OracleConnection connection, String schemaSrc, String tableSrc,
                                                 OrderedMap orderedMap) throws SQLException
    {
        if (orderedMap == null)
            orderedMap = new LinkedMap(99);
        String fetchStmtFmt = "SELECT RNID, SPACETABLE FROM \"%s\".\"%s\"";
        PrintfFormat spf = new PrintfFormat(fetchStmtFmt);
        String fetchStmt = spf.sprintf(new Object[]{schemaSrc, tableSrc});
        Statement stmt = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        stmt.setFetchSize(FETCHSIZE);
        ResultSet rs = stmt.executeQuery(fetchStmt);
        while (rs.next())
        {
            int size = rs.getMetaData().getColumnCount();
            Object[] values = new Object[size];
            for (int i = 0; i < size; i++)
            {
                values[i] = rs.getObject(i + 1);
            }
            Integer key = ((BigDecimal) values[0]).intValue();
            String name = (String) values[1];
            Pair pair = (Pair) orderedMap.get(key);
            if (pair == null)
                orderedMap.put(key, new Pair(null, name));
            else
                pair.second = name;
        }
        rs.close();
        stmt.close();
        return orderedMap;
    }
    protected void queryIgsetElement(OracleConvertJobContext jobContext,
                                     String srcschema, String srctable) throws SQLException
    {
        OracleConnection connection = jobContext.getOracleConnection();
        String fetchSrcStmtFmt = "SELECT IGDSELM FROM \"%s\".\"%s\" ORDER BY ROWID";
        PrintfFormat spf = new PrintfFormat(fetchSrcStmtFmt);
        String fetchSrcStmt = spf.sprintf(new Object[]{srcschema, srctable});
        Statement stmtSrc = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        stmtSrc.setFetchSize(FETCHSIZE);
        ResultSet rsSrc = stmtSrc.executeQuery(fetchSrcStmt);
        while (rsSrc.next())
        {
            byte[] raw = null;
            if (rsSrc.getMetaData().getColumnType(1) == Types.BLOB)
            {
                BLOB blob = (BLOB) rsSrc.getBlob(1);
                raw = getBytesFromBLOB(blob);
                blob.close();
            } else
            {
                raw = rsSrc.getBytes(1);
            }
            try
            {
                Element element = fetchBinaryElement(raw);
                jobContext.putFeatureCollection(element);
            } catch (Dgn7fileException e)
            {
                logger.warn("Dgn7Exception", e);
            }
        }
        rsSrc.close();
        stmtSrc.close();
    }
    protected void queryRawElement(OracleConvertJobContext jobContext,
                                   String srcschema, String srctable) throws SQLException
    {
        OracleConnection connection = jobContext.getOracleConnection();
        String fetchDestStmtFmt = "SELECT ELEMENT FROM \"%s\".\"%s\" ORDER BY ROWID";
        PrintfFormat spf = new PrintfFormat(fetchDestStmtFmt);
        String fetchDestStmt = spf.sprintf(new Object[]{srcschema, srctable});
        Statement stmtDest = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        stmtDest.setFetchSize(FETCHSIZE);
        ResultSet rsDest = stmtDest.executeQuery(fetchDestStmt);
        while (rsDest.next())
        {
            ARRAY rawsValue = ((OracleResultSet) rsDest).getARRAY(1);
            long[] rawData = rawsValue.getLongArray();
            byte[] comparessedValue;
            /*
            if (dataMode == TransferTask.DataMode.Normal)
            {
                comparessedValue = BinConverter.unmarshalByteArray(rawData, true);
            } else
            {
                comparessedValue = BinConverter.unmarshalCompactByteArray(rawData);
            }
            */
            comparessedValue = BinConverter.unmarshalByteArray(rawData, true);
            byte[] rawDest = ByteArrayCompressor.decompressByteArray(comparessedValue);
            try
            {
                Element element = fetchBinaryElement(rawDest);
                jobContext.putFeatureCollection(element);
            } catch (Dgn7fileException e)
            {
                logger.warn("Dgn7Exception:" + e.getMessage(), e);
            }
        }
        rsDest.close();
        stmtDest.close();
    }
    // Binary to Element
    private Element fetchBinaryElement(byte[] raws) throws Dgn7fileException
    {
        ByteBuffer buffer = ByteBuffer.wrap(raws);
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        short signature = buffer.getShort();
        // byte type = (byte) (buffer.get() & 0x7f);
        byte type = (byte) ((signature >>> 8) & 0x007f);
        // silly Bentley say contentLength is in 2-byte words
        // and ByteByffer uses raws.
        // track the record location
        int elementLength = (buffer.getShort() * 2) + 4;
        ElementType recordType = ElementType.forID(type);
        IElementHandler handler;
        handler = recordType.getElementHandler();
        Element dgnElement = (Element) handler.read(buffer, signature, elementLength);
        if (recordType.isComplexElement() && (elementLength < raws.length))
        {
            int offset = elementLength;
            while (offset < (raws.length - 4))
            {
                buffer.position(offset);
                signature = buffer.getShort();
                type = (byte) ((signature >>> 8) & 0x007f);
                elementLength = (buffer.getShort() * 2) + 4;
                if (raws.length < (offset + elementLength))
                {
                    System.out.println("Length not match:" + offset + ":" + buffer.position() + ":" + buffer.limit());
                    break;
                }
                recordType = ElementType.forID(type);
                handler = recordType.getElementHandler();
                if (handler != null)
                {
                    Element subElement = (Element) handler.read(buffer, signature, elementLength);
                    ((ComplexElement) dgnElement).add(subElement);
                    offset += elementLength;
                } else
                {
                    byte[] remain = new byte[buffer.remaining()];
                    System.arraycopy(raws, offset, remain, 0, buffer.remaining());
                    for (int i = 0; i < remain.length; i++)
                    {
                        if (remain[i] != 0)
                        {
                            logger.info("fetch element has some error. index=" + (offset + i) + ":value=" + remain[i]);
                            System.out.println("fetch element has some error. index=" + (offset + i) + ":value=" + remain[i]);
                        }
                    }
                    break;
                }
            }
        }
        return dgnElement;
    }
    /**
     * °õ¦æÂà´«¯Á¤Þ¹ÏÀɪº¤u§@
     *
     * @param context ¤u§@°õ¦æÀô¹Ò
     * @throws org.quartz.JobExecutionException exception
     */
    private void convertIndexDesignFile(JobExecutionContext context) throws JobExecutionException
    {
        File indexDir = new File(getDataPath(), "index");
        if (!indexDir.exists())
        {
            logger.info("index dir=" + indexDir + " not exist.");
            return;
        }
        if (!indexDir.isDirectory())
        {
            logger.info("index dir=" + indexDir + " is not a directory.");
        }
        File[] dgnFiles = indexDir.listFiles(new FilenameFilter()
        {
            public boolean accept(File dir, String name)
            {
                return name.toLowerCase().endsWith(".dgn");
            }
        });
        for (File dgnFile : dgnFiles)
        {
            IndexDgnConvertJobContext convertContext = new IndexDgnConvertJobContext(getDataPath());
            logger.debug("--- start dgnfile-" + dgnFile.toString() + " ---");
            try
            {
                convertContext.setExecutionContext(context);
                String dgnPaths[] = StringUtils.splitToArray(dgnFile.toString(), File.separator);
                convertContext.setFilename(dgnPaths[dgnPaths.length - 1]);
                FileInputStream fs = new FileInputStream(dgnFile);
                FileChannel fc = fs.getChannel();
                Dgn7fileReader reader = new Dgn7fileReader(fc, new Lock());
                convertContext.setReader(reader);
                scanIndexDgnElement(convertContext);
                convertContext.commitTransaction();
                convertContext.closeFeatureWriter();
                System.gc();
            } catch (FileNotFoundException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (Dgn7fileException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (IOException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (IllegalAttributeException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (SchemaException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            }
        }
    }
    protected void scanIndexDgnElement(IndexDgnConvertJobContext convertContext)
            throws Dgn7fileException, IOException, IllegalAttributeException, SchemaException
    {
        Dgn7fileReader reader = convertContext.getReader();
        int count = 0;
        Element lastComplex = null;
        while (reader.hasNext())
        {
            Dgn7fileReader.Record record = reader.nextElement();
            if (record.element() != null)
            {
                Element element = (Element) record.element();
                ElementType type = element.getElementType();
                if ((!type.isComplexElement()) && (!element.isComponentElement()))
                {
                    lastComplex = null;
                    processIndexElement(element, convertContext);
                } else if (element.isComponentElement())
                {
                    if (lastComplex != null)
                    {
                        ((ComplexElement) lastComplex).add(element);
                    }
                } else if (type.isComplexElement())
                {
                    if (lastComplex == null)
                    {
                        lastComplex = element;
                    } else
                    {
                        processIndexElement(element, convertContext);
                        lastComplex = element;
                    }
                }
            }
            count++;
        }
        logger.debug("ElementRecord Count=" + count);
    }
    private void processIndexElement(Element element, IndexDgnConvertJobContext convertContext) throws IllegalAttributeException, SchemaException
    {
        if (element instanceof TextElement)
        {
            convertContext.putFeatureCollection(element);
        }
    }
    /**
     * °õ¦æÂà´«¨ä¥L³]­p¹ÏÀɪº¤u§@
     *
     * @param context jobContext
     * @throws org.quartz.JobExecutionException exception
     */
    private void convertOtherDesignFile(JobExecutionContext context) throws JobExecutionException
    {
        File otherDir = new File(getDataPath(), "other");
        if (!otherDir.exists())
        {
            logger.info("other dir=" + otherDir + " not exist.");
            return;
        }
        if (!otherDir.isDirectory())
        {
            logger.info("other dir=" + otherDir + " is not a directory.");
        }
        File[] dgnFiles = otherDir.listFiles(new FilenameFilter()
        {
            public boolean accept(File dir, String name)
            {
                return name.toLowerCase().endsWith(".dgn");
            }
        });
        for (File dgnFile : dgnFiles)
        {
            GeneralDgnConvertJobContext convertContext = new GeneralDgnConvertJobContext(getDataPath());
            logger.info("--- start dgnfile-" + dgnFile.toString() + " ---");
            try
            {
                convertContext.setExecutionContext(context);
                String dgnPaths[] = StringUtils.splitToArray(dgnFile.toString(), File.separator);
                convertContext.setFilename(dgnPaths[dgnPaths.length - 1]);
                FileInputStream fs = new FileInputStream(dgnFile);
                FileChannel fc = fs.getChannel();
                Dgn7fileReader reader = new Dgn7fileReader(fc, new Lock());
                convertContext.setReader(reader);
                scanOtherDgnElement(convertContext);
                convertContext.commitTransaction();
                convertContext.closeFeatureWriter();
                System.gc();
            } catch (FileNotFoundException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (Dgn7fileException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (IOException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (IllegalAttributeException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (SchemaException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            }
        }
    }
    public void scanOtherDgnElement(GeneralDgnConvertJobContext convertContext)
            throws Dgn7fileException, IOException, IllegalAttributeException, SchemaException
    {
        Dgn7fileReader reader = convertContext.getReader();
        int count = 0;
        Element lastComplex = null;
        while (reader.hasNext())
        {
            Dgn7fileReader.Record record = reader.nextElement();
            if (record.element() != null)
            {
                Element element = (Element) record.element();
                ElementType type = element.getElementType();
                if ((!type.isComplexElement()) && (!element.isComponentElement()))
                {
                    lastComplex = null;
                    processOtherElement(element, convertContext);
                } else if (element.isComponentElement())
                {
                    if (lastComplex != null)
                    {
                        ((ComplexElement) lastComplex).add(element);
                    }
                } else if (type.isComplexElement())
                {
                    if (lastComplex == null)
                    {
                        lastComplex = element;
                    } else
                    {
                        processOtherElement(element, convertContext);
                        lastComplex = element;
                    }
                }
            }
            count++;
        }
        logger.debug("ElementRecord Count=" + count);
    }
    private void processOtherElement(Element element, GeneralDgnConvertJobContext convertContext)
            throws IllegalAttributeException, SchemaException
    {
        convertContext.putFeatureCollection(element);
    }
    private void clearOutputDirectory()
    {
        File outDataPath = new File(getDataPath(), OracleConvertJobContext.SHPOUTPATH);
        if (outDataPath.exists() && outDataPath.isDirectory())
        {
            deleteFilesInPath(outDataPath);
        }
        outDataPath = new File(getDataPath(), IndexDgnConvertJobContext.SHPOUTPATH);
        if (outDataPath.exists() && outDataPath.isDirectory())
        {
            deleteFilesInPath(outDataPath);
        }
        outDataPath = new File(getDataPath(), GeneralDgnConvertJobContext.SHPOUTPATH);
        if (outDataPath.exists() && outDataPath.isDirectory())
        {
            deleteFilesInPath(outDataPath);
        }
    }
    private void deleteFilesInPath(File outDataPath)
    {
        deleteFilesInPath(outDataPath, true);
    }
    private void deleteFilesInPath(File outDataPath, boolean removeSubDir)
    {
        if (!outDataPath.isDirectory())
        {
            return;
        }
        File[] files = outDataPath.listFiles();
        for (File file : files)
        {
            if (file.isFile())
            {
                if (!file.delete())
                {
                    logger.info("Cannot delete file-" + file.toString());
                }
            } else if (file.isDirectory())
            {
                deleteFilesInPath(file, removeSubDir);
                if (removeSubDir)
                {
                    if (file.delete())
                    {
                        logger.info("Cannot delete dir-" + file.toString());
                    }
                }
            }
        }
    }
    private void convertFeatureDesignFile(JobExecutionContext context) throws JobExecutionException
    {
        File elminDir = new File(getDataPath(), "elmin");
        if (!elminDir.exists())
        {
            logger.info("elmin dir=" + elminDir + " not exist.");
            return;
        }
        if (!elminDir.isDirectory())
        {
            logger.info("elmin dir=" + elminDir + " is not a directory.");
        }
        File[] dgnFiles = elminDir.listFiles(new FilenameFilter()
        {
            public boolean accept(File dir, String name)
            {
                return name.toLowerCase().endsWith(".dgn");
            }
        });
        for (File dgnFile : dgnFiles)
        {
            FeatureDgnConvertJobContext convertContext = new FeatureDgnConvertJobContext(getDataPath(), _filterPath);
            logger.info("--- start dgnfile-" + dgnFile.toString() + " ---");
            try
            {
                convertContext.setExecutionContext(context);
                String dgnPaths[] = StringUtils.splitToArray(dgnFile.toString(), File.separator);
                convertContext.setFilename(dgnPaths[dgnPaths.length - 1]);
                FileInputStream fs = new FileInputStream(dgnFile);
                FileChannel fc = fs.getChannel();
                Dgn7fileReader reader = new Dgn7fileReader(fc, new Lock());
                convertContext.setReader(reader);
                scanFeatureDgnElement(convertContext);
                convertContext.commitTransaction();
                convertContext.closeFeatureWriter();
                System.gc();
            } catch (FileNotFoundException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (Dgn7fileException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (IOException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (IllegalAttributeException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            } catch (SchemaException e)
            {
                convertContext.rollbackTransaction();
                logger.warn(e.getMessage(), e);
                throw new JobExecutionException(e.getMessage(), e);
            }
        }
    }
    public void scanFeatureDgnElement(FeatureDgnConvertJobContext convertContext)
            throws Dgn7fileException, IOException, IllegalAttributeException, SchemaException
    {
        Dgn7fileReader reader = convertContext.getReader();
        int count = 0;
        Element lastComplex = null;
        while (reader.hasNext())
        {
            Dgn7fileReader.Record record = reader.nextElement();
            if (record.element() != null)
            {
                Element element = (Element) record.element();
                ElementType type = element.getElementType();
                if ((!type.isComplexElement()) && (!element.isComponentElement()))
                {
                    lastComplex = null;
                    processFeatureElement(element, convertContext);
                } else if (element.isComponentElement())
                {
                    if (lastComplex != null)
                    {
                        ((ComplexElement) lastComplex).add(element);
                    }
                } else if (type.isComplexElement())
                {
                    if (lastComplex == null)
                    {
                        lastComplex = element;
                    } else
                    {
                        processFeatureElement(element, convertContext);
                        lastComplex = element;
                    }
                }
            }
            count++;
        }
        logger.debug("ElementRecord Count=" + count);
    }
    private void processFeatureElement(Element element, FeatureDgnConvertJobContext convertContext)
            throws IllegalAttributeException, SchemaException
    {
        convertContext.putFeatureCollection(element);
    }
    private void createDummyFeatureFile(JobExecutionContext context) throws JobExecutionException
    {
        /*
        DummyFeatureConvertJobContext convertContext = new DummyFeatureConvertJobContext(getDataPath(), _filterPath);
        try {
            convertContext.startTransaction();
            convertContext.commitTransaction();
            convertContext.closeFeatureWriter();
        } catch (IOException e)
        {
            logger.warn(e.getMessage(), e);
            throw new JobExecutionException(e.getMessage(), e);
        }
        */
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleConvertJobContext.java
New file
@@ -0,0 +1,347 @@
package com.ximple.eofms.jobs;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.nio.charset.Charset;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.transaction.memory.PessimisticMapWrapper;
import org.apache.commons.transaction.util.CommonsLoggingLogger;
import org.apache.commons.transaction.util.LoggerFacade;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.indexed.IndexedShapefileDataStore;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SimpleFeature;
import org.quartz.JobExecutionContext;
import org.xml.sax.SAXException;
import com.vividsolutions.jts.util.Assert;
import com.ximple.eofms.filter.AbstractFLinkageDispatchableFilter;
import com.ximple.eofms.filter.ElementDispatcher;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.FrammeAttributeData;
import com.ximple.io.dgn7.ComplexElement;
public class OracleConvertJobContext extends AbstractOracleJobContext
{
    static Log logger = LogFactory.getLog(OracleConvertJobContext.class);
    static final LoggerFacade sLogger = new CommonsLoggingLogger(logger);
    static final String SHPOUTPATH = "shpout";
    private OracleElementLogger elmLogger = null;
    static
    {
        try
        {
            DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        } catch (SQLException e)
        {
            Assert.shouldNeverReachHere(e.getMessage());
        }
    }
    private String _filterConfig;
    private ElementDispatcher elementDispatcher;
    private HashMap featuresContext = new HashMap();
    private HashMap<String, FeatureWriter> featuresWriterContext = new HashMap<String, FeatureWriter>();
    private PessimisticMapWrapper txFeaturesContext;
    private JobExecutionContext executionContext;
    private String dataOut = null;
    private String _convertDB = null;
    private String _convertFile = null;
    private String currentSchema = null;
    private boolean schemaChanged = false;
    private String _convertElementIn = null;
    public OracleConvertJobContext(String filterConfig)
    {
        properties = new Properties();
        _filterConfig = filterConfig;
        elementDispatcher = createElementDispatcher();
        txFeaturesContext = new PessimisticMapWrapper(featuresContext, sLogger);
    }
    private ElementDispatcher createElementDispatcher()
    {
        try
        {
            URL rulesURL = ElementDispatcher.class.getResource("ElementDispatcherRules.xml");
            assert rulesURL != null;
            Digester digester = DigesterLoader.createDigester(rulesURL);
            URL filterURL = null;
            if (_filterConfig != null)
            {
                File config = new File(_filterConfig);
                if (config.exists())
                {
                    filterURL = config.toURI().toURL();
                }
            }
            if (filterURL == null)
            {
                // config = new File("conf/DefaultConvertShpFilter.xml");
                filterURL = this.getClass().getResource("/conf/DefaultConvertShpFilter.xml");
                // filterURL = this.getClass().getResource("/conf/ConvertShpFilterForLevel.xml");
            }
            assert filterURL != null;
            return (ElementDispatcher) digester.parse(filterURL);
        } catch (UnsupportedEncodingException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        } catch (MalformedURLException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        } catch (IOException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        } catch (SAXException e)
        {
            logger.info(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    public void putFeatureCollection(Element element)
    {
        assert elementDispatcher != null;
        // §PÂ_¬O§_²Å©M±ø¥ó
        Feature feature = elementDispatcher.execute(element);
        if (feature == null)
        {
            boolean isEmptySize = false;
            FrammeAttributeData linkage =
                    AbstractFLinkageDispatchableFilter.getFeatureLinkage(element);
            logger.warn("Unknown Element:" + element.getElementType().toString() +
                    ":type=" + element.getType() + ":lv=" + element.getLevelIndex() + ":id=" +
                    (linkage == null ? "NULL" : (linkage.getFsc() + "|" + linkage.getComponentID())));
            if (element instanceof ComplexElement)
            {
                ComplexElement complex = (ComplexElement) element;
                logger.warn("----Complex Element size=" + complex.size() + ":" +
                        (linkage == null ? "NULL" : (linkage.getUfid())));
                isEmptySize = true;
            }
            if (getElementLogging() && (!isEmptySize))
            {
                getElementLogger().logElement(element, getCurrentSchema());
            }
            return;
        }
        if (!txFeaturesContext.containsKey(feature.getFeatureType()))
        {
            txFeaturesContext.put(feature.getFeatureType(), new ArrayList());
        }
        ArrayList arrayList = (ArrayList) txFeaturesContext.get(feature.getFeatureType());
        arrayList.add(feature);
    }
    public void startTransaction()
    {
        //txFeaturesContext.startTransaction();
    }
    public void commitTransaction()
    {
        if (!txFeaturesContext.isEmpty())
        {
            logger.debug("Transaction size = " + txFeaturesContext.size());
            //txFeaturesContext.commitTransaction();
        } else
        {
            logger.debug("Transaction is empty.");
        }
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
        if (this.getElementLogger() != null)
            this.getElementLogger().flashLogging();
    }
    public void rollbackTransaction()
    {
        //txFeaturesContext.rollbackTransaction();
        if (!featuresContext.isEmpty())
        {
            updateDataStore();
        }
    }
    private void updateDataStore()
    {
        Iterator it = featuresContext.keySet().iterator();
        try
        {
            while (it.hasNext())
            {
                FeatureType featureType = (FeatureType) it.next();
                File sfile = new File(getDataOutPath() + File.separator + featureType.getTypeName());
                logger.debug("Begin Save shapefile:" + sfile.toURI());
                FeatureWriter writer = null;
                if (featuresWriterContext.containsKey(featureType.getTypeName()))
                {
                    writer = featuresWriterContext.get(featureType.getTypeName());
                } else
                {
                    /*
                    ShapefileDataStore shapefileDataStore = new ShapefileDataStore(sfile.toURI().toURL(),
                            true, Charset.forName("UTF-8"));
                    */
                    if (!sfile.exists())
                    {
                        ShapefileDataStore shapefileDataStore = new IndexedShapefileDataStore(sfile.toURI().toURL(),
                                null, true, true, IndexedShapefileDataStore.TREE_QIX, Charset.forName("UTF-8"));
                        shapefileDataStore.createSchema(featureType);
                        writer = shapefileDataStore.getFeatureWriter(featureType.getTypeName(),
                                Transaction.AUTO_COMMIT);
                    } else {
                        ShapefileDataStore shapefileDataStore = new IndexedShapefileDataStore(sfile.toURI().toURL(),
                                null, true, true, IndexedShapefileDataStore.TREE_QIX, Charset.forName("UTF-8"));
                        writer = shapefileDataStore.getFeatureWriterAppend(featureType.getTypeName(),
                                Transaction.AUTO_COMMIT);
                    }
                    featuresWriterContext.put(featureType.getTypeName(), writer);
                }
                ArrayList features = (ArrayList) featuresContext.get(featureType);
                Iterator itFeature = features.iterator();
                while (itFeature.hasNext())
                {
                    Feature feature = (Feature) itFeature.next();
                    ((SimpleFeature) writer.next()).setAttributes(feature.getAttributes(null));
                }
                //writer.close();
                logger.debug("End Save shapefile:" + sfile.toURI());
            }
            featuresContext.clear();
        } catch (MalformedURLException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IllegalAttributeException e)
        {
            logger.error(e.getMessage(), e);
        } catch (IOException e)
        {
            logger.error(e.getMessage(), e);
        }
    }
    public JobExecutionContext getExecutionContext()
    {
        return executionContext;
    }
    public void setExecutionContext(JobExecutionContext context)
    {
        executionContext = context;
    }
    /**
     * Ãö³¬³]³Æ¼g¤J¾¹
     *
     * @throws IOException IOµo¥Í¿ù»~
     */
    public void closeFeatureWriter() throws IOException
    {
        for (FeatureWriter featureWriter : this.featuresWriterContext.values())
        {
            featureWriter.close();
        }
        this.featuresWriterContext.clear();
    }
    /**
     * ¨ú±o¸ê®Æ¿é¥X¸ô®|
     *
     * @return ¸ô®|ªº¦r¦ê
     */
    public String getDataOutPath()
    {
        if (dataOut == null)
        {
            File outPath = new File(getDataPath(), SHPOUTPATH);
            if (!outPath.exists())
            {
                outPath.mkdir();
            } else if (!outPath.isDirectory())
            {
                outPath.mkdir();
            }
            dataOut = outPath.toString();
        }
        return dataOut;
    }
    public void setConvertDB(String convertDB)
    {
        _convertDB = convertDB;
    }
    public void setConvertFile(String convertFile)
    {
        _convertFile = convertFile;
    }
    protected OracleElementLogger getElementLogger()
    {
        if (elmLogger == null)
        {
            elmLogger = new OracleElementLogger(getOracleConnection());
            elmLogger.setDataPath(this.getDataPath());
        }
        return elmLogger;
    }
    public String getCurrentSchema()
    {
        return currentSchema;
    }
    public void setCurrentSchema(String querySchema)
    {
        this.currentSchema = querySchema;
        this.schemaChanged = true;
    }
    public void setConvertElementIn(String convertElementIn)
    {
        _convertElementIn = convertElementIn;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleElementLogger.java
New file
@@ -0,0 +1,314 @@
package com.ximple.eofms.jobs;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.vividsolutions.jts.util.Assert;
import oracle.sql.BLOB;
import com.ximple.eofms.util.PrintfFormat;
import com.ximple.io.dgn7.ArcElement;
import com.ximple.io.dgn7.ComplexChainElement;
import com.ximple.io.dgn7.ComplexShapeElement;
import com.ximple.io.dgn7.Element;
import com.ximple.io.dgn7.EllipseElement;
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;
public class OracleElementLogger
{
    static Log logger = LogFactory.getLog(OracleElementLogger.class);
    private static final String ELMOUTPATH = "elmout";
    private static final String TAB_IGDSSEED = "SD$IGDSSET_SEED";
    private Connection connection;
    private String dataOut = null;
    private String dataPath;
    private String currentSchema;
    private boolean schemaChanged;
    private FileOutputStream fos = null;
    private FileChannel fch = null;
    private int logCount = 0;
    public OracleElementLogger(Connection connection)
    {
        this.connection = connection;
    }
    public String getDataOutPath()
    {
        if (dataOut == null)
        {
            File outPath = new File(getDataPath(), ELMOUTPATH);
            if (!outPath.exists())
            {
                outPath.mkdir();
            } else if (!outPath.isDirectory())
            {
                outPath.mkdir();
            }
            dataOut = outPath.toString();
        }
        return dataOut;
    }
    public String getDataPath()
    {
        return dataPath;
    }
    public void setDataPath(String dataPath)
    {
        this.dataPath = dataPath;
    }
    public void logElement(Element element, String currentSchema)
    {
        if ((this.currentSchema == null) ||
            (!this.currentSchema.equalsIgnoreCase(currentSchema)))
        {
            schemaChanged = true;
            this.currentSchema = currentSchema;
            try
            {
                createNewStream();
            } catch (IOException e)
            {
                logger.warn(e.getMessage(), e);
                return;
            } catch (SQLException e)
            {
                logger.warn(e.getMessage(), e);
                return;
            }
        } else
        {
            if (fch == null)
            {
                try
                {
                    createNewStream();
                } catch (IOException e)
                {
                    logger.warn(e.getMessage(), e);
                    return;
                } catch (SQLException e)
                {
                    logger.warn(e.getMessage(), e);
                    return;
                }
            }
        }
        if (fch != null)
        {
            ByteBuffer buf = null;
            if (element instanceof LineElement)
            {
                int size = LineElement.ElementHandler.getInstance().getLength(element);
                buf = ByteBuffer.allocate(size * 2);
                LineElement.ElementHandler.getInstance().write(buf, element);
            } else if (element instanceof ShapeElement)
            {
                int size = ShapeElement.ElementHandler.getInstance().getLength(element);
                buf = ByteBuffer.allocate(size * 2);
                ShapeElement.ElementHandler.getInstance().write(buf, element);
            } else if (element instanceof LineStringElement)
            {
                int size = LineStringElement.ElementHandler.getInstance().getLength(element);
                buf = ByteBuffer.allocate(size * 2);
                LineStringElement.ElementHandler.getInstance().write(buf, element);
            } else if (element instanceof ComplexChainElement)
            {
                int size = ComplexChainElement.ElementHandler.getInstance().getLength(element);
                buf = ByteBuffer.allocate(size * 2);
                ComplexChainElement.ElementHandler.getInstance().write(buf, element);
            } else if (element instanceof ComplexShapeElement)
            {
                int size = ComplexShapeElement.ElementHandler.getInstance().getLength(element);
                buf = ByteBuffer.allocate(size * 2);
                ComplexShapeElement.ElementHandler.getInstance().write(buf, element);
            } else if (element instanceof ArcElement)
            {
                int size = ArcElement.ElementHandler.getInstance().getLength(element);
                buf = ByteBuffer.allocate(size * 2);
                ArcElement.ElementHandler.getInstance().write(buf, element);
            } else if (element instanceof EllipseElement)
            {
                int size = EllipseElement.ElementHandler.getInstance().getLength(element);
                buf = ByteBuffer.allocate(size * 2);
                EllipseElement.ElementHandler.getInstance().write(buf, element);
            } else if (element instanceof TextElement)
            {
                int size = TextElement.ElementHandler.getInstance().getLength(element);
                buf = ByteBuffer.allocate(size * 2);
                TextElement.ElementHandler.getInstance().write(buf, element);
            } else if (element instanceof TextNodeElement)
            {
                int size = TextNodeElement.ElementHandler.getInstance().getLength(element);
                buf = ByteBuffer.allocate(size * 2);
                TextNodeElement.ElementHandler.getInstance().write(buf, element);
            }
            if ((buf != null) && (fch != null))
            {
                try
                {
                    buf.position(0);
                    int size = fch.write(buf);
                    if (size != buf.limit())
                    {
                        long position = fch.position();
                        logger.info("Pos:" + position);
                    }
                } catch (IOException e)
                {
                    logger.warn(e.getMessage(), e);
                }
            }
        }
    }
    private void createNewStream() throws IOException, SQLException
    {
        if (fos != null)
        {
            putEndOfFileElement();
            fos.close();
            fos = null;
            fch = null;
        }
        File logFile = new File(getDataOutPath(), this.currentSchema + ".dgn");
        while (logFile.exists())
        {
            logFile = new File(getDataOutPath(), this.currentSchema + "-"
                    + (++logCount) +".dgn");
        }
        logger.warn("Create Dgn Logging File:" + logFile.toString());
        fos = new FileOutputStream(logFile);
        fch = fos.getChannel();
        prepareOutputElementStream();
        schemaChanged = false;
    }
    private void putEndOfFileElement() throws IOException
    {
        if (fch == null)
            return;
        ByteBuffer bf = ByteBuffer.allocate(4);
        bf.putInt(-1);
        fch.write(bf);
    }
    private void prepareOutputElementStream() throws SQLException, IOException
    {
        if (connection == null)
        {
            logger.warn("connection is null");
            return;
        }
        String fetchSrcStmtFmt = "SELECT IGDSELM FROM \"%s\".\"%s\" ORDER BY ROWID";
        PrintfFormat spf = new PrintfFormat(fetchSrcStmtFmt);
        String fetchSrcStmt = spf.sprintf(new Object[]{currentSchema, TAB_IGDSSEED});
        Statement stmtSrc = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
        ResultSet rsSrc = stmtSrc.executeQuery(fetchSrcStmt);
        while (rsSrc.next())
        {
            byte[] raw;
            if (rsSrc.getMetaData().getColumnType(1) == Types.BLOB)
            {
                BLOB blob = (BLOB) rsSrc.getBlob(1);
                raw = getBytesFromBLOB(blob);
                blob.close();
            } else
            {
                raw = rsSrc.getBytes(1);
            }
            if (raw != null)
            {
                putElementIntoStream(raw);
            }
        }
    }
    private void putElementIntoStream(byte[] raw) throws IOException
    {
        if (fch != null)
            fch.write(ByteBuffer.wrap(raw));
    }
    protected static byte[] getBytesFromBLOB(BLOB blob) throws SQLException
    {
        byte[] raw = null;
        int optimalSize = blob.getChunkSize();
        byte[] chunk = new byte[optimalSize];
        InputStream is = blob.getBinaryStream(0);
        ByteBuffer buffer = null;    // ByteBuffer.allocate(optimalSize);
        int len = 0;
        try
        {
            while ((len = (is.read(chunk))) != -1)
            {
                if (buffer != null)
                {
                    buffer.limit(buffer.limit() + len);
                } else
                {
                    buffer = ByteBuffer.allocate(len);
                }
                buffer.put(chunk);
            }
            is.close();
            buffer.position(0);
            raw = buffer.array();
        } catch (IOException e)
        {
            logger.warn(e.getMessage(), e);
            Assert.shouldNeverReachHere();
        }
        return raw;
    }
    public void flashLogging()
    {
        if (fos != null)
        {
            try
            {
                fos.close();
            } catch (IOException e)
            {
                logger.warn(e.getMessage(), e);
            }
            fos = null;
            fch = null;
        }
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleUpgradeBlob2UDTJob.java
New file
@@ -0,0 +1,60 @@
package com.ximple.eofms.jobs;
import java.sql.SQLException;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDatabaseMetaData;
import oracle.jdbc.OracleStatement;
public class OracleUpgradeBlob2UDTJob extends AbstractOracleDatabaseJob
{
    static Log logger = LogFactory.getLog(OracleUpgradeBlob2UDTJob.class);
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
        // Every job has its own job detail
        JobDetail jobDetail = context.getJobDetail();
        // The name is defined in the job definition
        String jobName = jobDetail.getName();
        // Log the time the job started
        logger.info(jobName + " fired at " + new Date());
        extractJobConfiguration(jobDetail);
        AbstractOracleJobContext jobContext = prepareJobContext(_filterPath);
        jobContext.setConnectionInfo(_oracleHost, _oraclePort, _oracleInstance);
        jobContext.setLogin(_username, _password);
        try
        {
            for (String orgSchema : _orgSchema)
            {
                exetcuteConvert(jobContext, orgSchema, _dataPath);
            }
        } catch (SQLException e)
        {
            throw new JobExecutionException("Database error.", e);
        }
    }
    protected AbstractOracleJobContext prepareJobContext(String filterPath)
    {
        return new OracleUpgradeJobContext();
    }
    private void exetcuteConvert(AbstractOracleJobContext jobContext,
                                 String orgSchema, String dataPath) throws SQLException
    {
        OracleConnection connection = jobContext.getOracleConnection();
        OracleDatabaseMetaData metaData = (OracleDatabaseMetaData) connection.getMetaData();
        OracleStatement statement = (OracleStatement) connection.createStatement();
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/OracleUpgradeJobContext.java
New file
@@ -0,0 +1,16 @@
package com.ximple.eofms.jobs;
public class OracleUpgradeJobContext extends AbstractOracleJobContext
{
    public void startTransaction()
    {
    }
    public void commitTransaction()
    {
    }
    public void rollbackTransaction()
    {
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/TWD97GeometryConverterDecorator.java
New file
@@ -0,0 +1,69 @@
package com.ximple.eofms.jobs;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.CoordinateSequenceFilter;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.util.Assert;
import com.ximple.eofms.util.TWDDatumConverter;
import com.ximple.io.dgn7.GeometryConverter;
public class TWD97GeometryConverterDecorator implements GeometryConverter
{
    private GeometryConverter converter;
    private TWD97ConvertFilter coordinatesFilter = new TWD97ConvertFilter();
    public TWD97GeometryConverterDecorator()
    {
    }
    public GeometryConverter getConverter()
    {
        return converter;
    }
    public void setConverter(GeometryConverter converter)
    {
        this.converter = converter;
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        if (converter == null) Assert.shouldNeverReachHere();
        coordinatesFilter.reset();
        Geometry geom = converter.toGeometry(factory);
        if (geom == null) return null;
        geom.apply(coordinatesFilter);
        return geom;
    }
    class TWD97ConvertFilter implements CoordinateSequenceFilter
    {
        public void filter(CoordinateSequence coordinateSequence, int i)
        {
            Coordinate pt =coordinateSequence.getCoordinate(i);
            Coordinate pt97 = TWDDatumConverter.fromTM2ToTWD97(pt);
            pt.x = pt97.x;
            pt.y = pt97.y;
            pt.z = pt97.z;
        }
        public boolean isDone()
        {
            return false;
        }
        public boolean isGeometryChanged()
        {
            return true;
        }
        public void reset()
        {
        }
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/Base64.java
New file
@@ -0,0 +1,551 @@
package com.ximple.eofms.util;
import java.util.Arrays;
public class Base64
{
    private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
    private static final int[] IA = new int[256];
    static
    {
        Arrays.fill(IA, -1);
        for (int i = 0, iS = CA.length; i < iS; i++)
            IA[CA[i]] = i;
        IA['='] = 0;
    }
    // ****************************************************************************************
    // *  char[] version
    // ****************************************************************************************
    /**
     * Encodes a raw byte array into a BASE64 <code>char[]</code> representation i accordance with RFC 2045.
     *
     * @param sArr    The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
     * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
     *                No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
     *                little faster.
     * @return A BASE64 encoded array. Never <code>null</code>.
     */
    public static char[] encodeToChar(byte[] sArr, boolean lineSep)
    {
        // Check special case
        int sLen = sArr != null ? sArr.length : 0;
        if (sLen == 0)
            return new char[0];
        int eLen = (sLen / 3) * 3;              // Length of even 24-bits.
        int cCnt = ((sLen - 1) / 3 + 1) << 2;   // Returned character count
        int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
        char[] dArr = new char[dLen];
        // Encode even 24-bits
        for (int s = 0, d = 0, cc = 0; s < eLen;)
        {
            // Copy next three bytes into lower 24 bits of int, paying attension to sign.
            int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
            // Encode the int into four chars
            dArr[d++] = CA[(i >>> 18) & 0x3f];
            dArr[d++] = CA[(i >>> 12) & 0x3f];
            dArr[d++] = CA[(i >>> 6) & 0x3f];
            dArr[d++] = CA[i & 0x3f];
            // Add optional line separator
            if (lineSep && ++cc == 19 && d < dLen - 2)
            {
                dArr[d++] = '\r';
                dArr[d++] = '\n';
                cc = 0;
            }
        }
        // Pad and encode last bits if source isn't even 24 bits.
        int left = sLen - eLen; // 0 - 2.
        if (left > 0)
        {
            // Prepare the int
            int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
            // Set last four chars
            dArr[dLen - 4] = CA[i >> 12];
            dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
            dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
            dArr[dLen - 1] = '=';
        }
        return dArr;
    }
    /**
     * Decodes a BASE64 encoded char array. All illegal characters will be ignored and can handle both arrays with
     * and without line separators.
     *
     * @param sArr The source array. <code>null</code> or length 0 will return an empty array.
     * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
     *         (including '=') isn't divideable by 4.  (I.e. definitely corrupted).
     */
    public static byte[] decode(char[] sArr)
    {
        // Check special case
        int sLen = sArr != null ? sArr.length : 0;
        if (sLen == 0)
            return new byte[0];
        // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
        // so we don't have to reallocate & copy it later.
        int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
        for (int i = 0; i < sLen; i++)  // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
            if (IA[sArr[i]] < 0)
                sepCnt++;
        // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
        if ((sLen - sepCnt) % 4 != 0)
            return null;
        int pad = 0;
        for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0;)
            if (sArr[i] == '=')
                pad++;
        int len = ((sLen - sepCnt) * 6 >> 3) - pad;
        byte[] dArr = new byte[len];       // Preallocate byte[] of exact length
        for (int s = 0, d = 0; d < len;)
        {
            // Assemble three bytes into an int from four "valid" characters.
            int i = 0;
            for (int j = 0; j < 4; j++)
            {   // j only increased if a valid char was found.
                int c = IA[sArr[s++]];
                if (c >= 0)
                    i |= c << (18 - j * 6);
                else
                    j--;
            }
            // Add the bytes
            dArr[d++] = (byte) (i >> 16);
            if (d < len)
            {
                dArr[d++] = (byte) (i >> 8);
                if (d < len)
                    dArr[d++] = (byte) i;
            }
        }
        return dArr;
    }
    /**
     * Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as
     * fast as {@link #decode(char[])}. The preconditions are:<br>
     * + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
     * + Line separator must be "\r\n", as specified in RFC 2045
     * + The array must not contain illegal characters within the encoded string<br>
     * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
     *
     * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
     * @return The decoded array of bytes. May be of length 0.
     */
    public byte[] decodeFast(char[] sArr)
    {
        // Check special case
        int sLen = sArr.length;
        if (sLen == 0)
            return new byte[0];
        int sIx = 0, eIx = sLen - 1;    // Start and end index after trimming.
        // Trim illegal chars from start
        while (sIx < eIx && IA[sArr[sIx]] < 0)
            sIx++;
        // Trim illegal chars from end
        while (eIx > 0 && IA[sArr[eIx]] < 0)
            eIx--;
        // get the padding count (=) (0, 1 or 2)
        int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0;  // Count '=' at end.
        int cCnt = eIx - sIx + 1;   // Content count including possible separators
        int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
        int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
        byte[] dArr = new byte[len];       // Preallocate byte[] of exact length
        // Decode all but the last 0 - 2 bytes.
        int d = 0;
        for (int cc = 0, eLen = (len / 3) * 3; d < eLen;)
        {
            // Assemble three bytes into an int from four "valid" characters.
            int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
            // Add the bytes
            dArr[d++] = (byte) (i >> 16);
            dArr[d++] = (byte) (i >> 8);
            dArr[d++] = (byte) i;
            // If line separator, jump over it.
            if (sepCnt > 0 && ++cc == 19)
            {
                sIx += 2;
                cc = 0;
            }
        }
        if (d < len)
        {
            // Decode last 1-3 bytes (incl '=') into 1-3 bytes
            int i = 0;
            for (int j = 0; sIx <= eIx - pad; j++)
                i |= IA[sArr[sIx++]] << (18 - j * 6);
            for (int r = 16; d < len; r -= 8)
                dArr[d++] = (byte) (i >> r);
        }
        return dArr;
    }
    // ****************************************************************************************
    // *  byte[] version
    // ****************************************************************************************
    /**
     * Encodes a raw byte array into a BASE64 <code>byte[]</code> representation i accordance with RFC 2045.
     *
     * @param sArr    The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
     * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
     *                No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
     *                little faster.
     * @return A BASE64 encoded array. Never <code>null</code>.
     */
    public static byte[] encodeToByte(byte[] sArr, boolean lineSep)
    {
        // Check special case
        int sLen = sArr != null ? sArr.length : 0;
        if (sLen == 0)
            return new byte[0];
        int eLen = (sLen / 3) * 3;                              // Length of even 24-bits.
        int cCnt = ((sLen - 1) / 3 + 1) << 2;                   // Returned character count
        int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
        byte[] dArr = new byte[dLen];
        // Encode even 24-bits
        for (int s = 0, d = 0, cc = 0; s < eLen;)
        {
            // Copy next three bytes into lower 24 bits of int, paying attension to sign.
            int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
            // Encode the int into four chars
            dArr[d++] = (byte) CA[(i >>> 18) & 0x3f];
            dArr[d++] = (byte) CA[(i >>> 12) & 0x3f];
            dArr[d++] = (byte) CA[(i >>> 6) & 0x3f];
            dArr[d++] = (byte) CA[i & 0x3f];
            // Add optional line separator
            if (lineSep && ++cc == 19 && d < dLen - 2)
            {
                dArr[d++] = '\r';
                dArr[d++] = '\n';
                cc = 0;
            }
        }
        // Pad and encode last bits if source isn't an even 24 bits.
        int left = sLen - eLen; // 0 - 2.
        if (left > 0)
        {
            // Prepare the int
            int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
            // Set last four chars
            dArr[dLen - 4] = (byte) CA[i >> 12];
            dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f];
            dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
            dArr[dLen - 1] = '=';
        }
        return dArr;
    }
    /**
     * Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with
     * and without line separators.
     *
     * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
     * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
     *         (including '=') isn't divideable by 4. (I.e. definitely corrupted).
     */
    public static byte[] decode(byte[] sArr)
    {
        // Check special case
        int sLen = sArr.length;
        // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
        // so we don't have to reallocate & copy it later.
        int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
        for (int i = 0; i < sLen; i++)      // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
            if (IA[sArr[i] & 0xff] < 0)
                sepCnt++;
        // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
        if ((sLen - sepCnt) % 4 != 0)
            return null;
        int pad = 0;
        for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0;)
            if (sArr[i] == '=')
                pad++;
        int len = ((sLen - sepCnt) * 6 >> 3) - pad;
        byte[] dArr = new byte[len];       // Preallocate byte[] of exact length
        for (int s = 0, d = 0; d < len;)
        {
            // Assemble three bytes into an int from four "valid" characters.
            int i = 0;
            for (int j = 0; j < 4; j++)
            {   // j only increased if a valid char was found.
                int c = IA[sArr[s++] & 0xff];
                if (c >= 0)
                    i |= c << (18 - j * 6);
                else
                    j--;
            }
            // Add the bytes
            dArr[d++] = (byte) (i >> 16);
            if (d < len)
            {
                dArr[d++] = (byte) (i >> 8);
                if (d < len)
                    dArr[d++] = (byte) i;
            }
        }
        return dArr;
    }
    /**
     * Decodes a BASE64 encoded byte array that is known to be resonably well formatted. The method is about twice as
     * fast as {@link #decode(byte[])}. The preconditions are:<br>
     * + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
     * + Line separator must be "\r\n", as specified in RFC 2045
     * + The array must not contain illegal characters within the encoded string<br>
     * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
     *
     * @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
     * @return The decoded array of bytes. May be of length 0.
     */
    public static byte[] decodeFast(byte[] sArr)
    {
        // Check special case
        int sLen = sArr.length;
        if (sLen == 0)
            return new byte[0];
        int sIx = 0, eIx = sLen - 1;    // Start and end index after trimming.
        // Trim illegal chars from start
        while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0)
            sIx++;
        // Trim illegal chars from end
        while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0)
            eIx--;
        // get the padding count (=) (0, 1 or 2)
        int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0;  // Count '=' at end.
        int cCnt = eIx - sIx + 1;   // Content count including possible separators
        int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
        int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
        byte[] dArr = new byte[len];       // Preallocate byte[] of exact length
        // Decode all but the last 0 - 2 bytes.
        int d = 0;
        for (int cc = 0, eLen = (len / 3) * 3; d < eLen;)
        {
            // Assemble three bytes into an int from four "valid" characters.
            int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
            // Add the bytes
            dArr[d++] = (byte) (i >> 16);
            dArr[d++] = (byte) (i >> 8);
            dArr[d++] = (byte) i;
            // If line separator, jump over it.
            if (sepCnt > 0 && ++cc == 19)
            {
                sIx += 2;
                cc = 0;
            }
        }
        if (d < len)
        {
            // Decode last 1-3 bytes (incl '=') into 1-3 bytes
            int i = 0;
            for (int j = 0; sIx <= eIx - pad; j++)
                i |= IA[sArr[sIx++]] << (18 - j * 6);
            for (int r = 16; d < len; r -= 8)
                dArr[d++] = (byte) (i >> r);
        }
        return dArr;
    }
    // ****************************************************************************************
    // * String version
    // ****************************************************************************************
    /**
     * Encodes a raw byte array into a BASE64 <code>String</code> representation i accordance with RFC 2045.
     *
     * @param sArr    The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
     * @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
     *                No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
     *                little faster.
     * @return A BASE64 encoded array. Never <code>null</code>.
     */
    public static String encodeToString(byte[] sArr, boolean lineSep)
    {
        // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower.
        return new String(encodeToChar(sArr, lineSep));
    }
    /**
     * Decodes a BASE64 encoded <code>String</code>. All illegal characters will be ignored and can handle both strings with
     * and without line separators.<br>
     * <b>Note!</b> It can be up to about 2x the speed to call <code>decode(str.toCharArray())</code> instead. That
     * will create a temporary array though. This version will use <code>str.charAt(i)</code> to iterate the string.
     *
     * @param str The source string. <code>null</code> or length 0 will return an empty array.
     * @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
     *         (including '=') isn't divideable by 4.  (I.e. definitely corrupted).
     */
    public static byte[] decode(String str)
    {
        // Check special case
        int sLen = str != null ? str.length() : 0;
        if (sLen == 0)
            return new byte[0];
        // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
        // so we don't have to reallocate & copy it later.
        int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
        for (int i = 0; i < sLen; i++)  // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
            if (IA[str.charAt(i)] < 0)
                sepCnt++;
        // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
        if ((sLen - sepCnt) % 4 != 0)
            return null;
        // Count '=' at end
        int pad = 0;
        for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0;)
            if (str.charAt(i) == '=')
                pad++;
        int len = ((sLen - sepCnt) * 6 >> 3) - pad;
        byte[] dArr = new byte[len];       // Preallocate byte[] of exact length
        for (int s = 0, d = 0; d < len;)
        {
            // Assemble three bytes into an int from four "valid" characters.
            int i = 0;
            for (int j = 0; j < 4; j++)
            {   // j only increased if a valid char was found.
                int c = IA[str.charAt(s++)];
                if (c >= 0)
                    i |= c << (18 - j * 6);
                else
                    j--;
            }
            // Add the bytes
            dArr[d++] = (byte) (i >> 16);
            if (d < len)
            {
                dArr[d++] = (byte) (i >> 8);
                if (d < len)
                    dArr[d++] = (byte) i;
            }
        }
        return dArr;
    }
    /**
     * Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as
     * fast as {@link #decode(String)}. The preconditions are:<br>
     * + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
     * + Line separator must be "\r\n", as specified in RFC 2045
     * + The array must not contain illegal characters within the encoded string<br>
     * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
     *
     * @param s The source string. Length 0 will return an empty array. <code>null</code> will throw an exception.
     * @return The decoded array of bytes. May be of length 0.
     */
    public static byte[] decodeFast(String s)
    {
        // Check special case
        int sLen = s.length();
        if (sLen == 0)
            return new byte[0];
        int sIx = 0, eIx = sLen - 1;    // Start and end index after trimming.
        // Trim illegal chars from start
        while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0)
            sIx++;
        // Trim illegal chars from end
        while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0)
            eIx--;
        // get the padding count (=) (0, 1 or 2)
        int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0;  // Count '=' at end.
        int cCnt = eIx - sIx + 1;   // Content count including possible separators
        int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0;
        int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
        byte[] dArr = new byte[len];       // Preallocate byte[] of exact length
        // Decode all but the last 0 - 2 bytes.
        int d = 0;
        for (int cc = 0, eLen = (len / 3) * 3; d < eLen;)
        {
            // Assemble three bytes into an int from four "valid" characters.
            int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)];
            // Add the bytes
            dArr[d++] = (byte) (i >> 16);
            dArr[d++] = (byte) (i >> 8);
            dArr[d++] = (byte) i;
            // If line separator, jump over it.
            if (sepCnt > 0 && ++cc == 19)
            {
                sIx += 2;
                cc = 0;
            }
        }
        if (d < len)
        {
            // Decode last 1-3 bytes (incl '=') into 1-3 bytes
            int i = 0;
            for (int j = 0; sIx <= eIx - pad; j++)
                i |= IA[s.charAt(sIx++)] << (18 - j * 6);
            for (int r = 16; d < len; r -= 8)
                dArr[d++] = (byte) (i >> r);
        }
        return dArr;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/BinConverter.java
New file
@@ -0,0 +1,363 @@
package com.ximple.eofms.util;
//~--- JDK imports ------------------------------------------------------------
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.LongBuffer;
/**
 * BinConverter
 * User: Ulysses
 * Date: 2007/9/17
 * Time: ¤W¤È 01:13:13
 */
public class BinConverter
{
    // our table for binhex conversion
    final static char[] HEXTAB =
            {
                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
            };
    /**
     * gets bytes from an array into a long
     *
     * @param buffer      where to get the bytes
     * @param nStartIndex index from where to read the data
     * @return the 64bit integer
     */
    public static long byteArrayToLong(byte[] buffer, int nStartIndex)
    {
        return (((long) buffer[nStartIndex]) << 56) | (((long) buffer[nStartIndex + 1] & 0x0ffL) << 48)
                | (((long) buffer[nStartIndex + 2] & 0x0ffL) << 40) | (((long) buffer[nStartIndex + 3] & 0x0ffL) << 32)
                | (((long) buffer[nStartIndex + 4] & 0x0ffL) << 24) | (((long) buffer[nStartIndex + 5] & 0x0ffL) << 16)
                | (((long) buffer[nStartIndex + 6] & 0x0ffL) << 8) | ((long) buffer[nStartIndex + 7] & 0x0ff);
    }
    /**
     * converts a long o bytes which are put into a given array
     *
     * @param lValue      the 64bit integer to convert
     * @param buffer      the target buffer
     * @param nStartIndex where to place the bytes in the buffer
     */
    public static void longToByteArray(long lValue, byte[] buffer, int nStartIndex)
    {
        buffer[nStartIndex] = (byte) (lValue >>> 56);
        buffer[nStartIndex + 1] = (byte) ((lValue >>> 48) & 0x0ff);
        buffer[nStartIndex + 2] = (byte) ((lValue >>> 40) & 0x0ff);
        buffer[nStartIndex + 3] = (byte) ((lValue >>> 32) & 0x0ff);
        buffer[nStartIndex + 4] = (byte) ((lValue >>> 24) & 0x0ff);
        buffer[nStartIndex + 5] = (byte) ((lValue >>> 16) & 0x0ff);
        buffer[nStartIndex + 6] = (byte) ((lValue >>> 8) & 0x0ff);
        buffer[nStartIndex + 7] = (byte) lValue;
    }
    /**
     * converts values from an integer array to a long
     *
     * @param buffer      where to get the bytes
     * @param nStartIndex index from where to read the data
     * @return the 64bit integer
     */
    public static long intArrayToLong(int[] buffer, int nStartIndex)
    {
        return (((long) buffer[nStartIndex]) << 32) | (((long) buffer[nStartIndex + 1]) & 0x0ffffffffL);
    }
    /**
     * converts a long to integers which are put into a given array
     *
     * @param lValue      the 64bit integer to convert
     * @param buffer      the target buffer
     * @param nStartIndex where to place the bytes in the buffer
     */
    public static void longToIntArray(long lValue, int[] buffer, int nStartIndex)
    {
        buffer[nStartIndex] = (int) (lValue >>> 32);
        buffer[nStartIndex + 1] = (int) lValue;
    }
    /**
     * makes a long from two integers (treated unsigned)
     *
     * @param nLo lower 32bits
     * @param nHi higher 32bits
     * @return the built long
     */
    public static long makeLong(int nLo, int nHi)
    {
        return (((long) nHi << 32) | ((long) nLo & 0x00000000ffffffffL));
    }
    /**
     * gets the lower 32 bits of a long
     *
     * @param lVal the long integer
     * @return lower 32 bits
     */
    public static int longLo32(long lVal)
    {
        return (int) lVal;
    }
    /**
     * gets the higher 32 bits of a long
     *
     * @param lVal the long integer
     * @return higher 32 bits
     */
    public static int longHi32(long lVal)
    {
        return (int) ((long) (lVal >>> 32));
    }
    /**
     * converts a byte array to a binhex string
     *
     * @param data the byte array
     * @return the binhex string
     */
    public static String bytesToBinHex(byte[] data)
    {
        // just map the call
        return bytesToBinHex(data, 0, data.length);
    }
    /**
     * converts a byte array to a binhex string
     *
     * @param data        the byte array
     * @param nStartPos   start index where to get the bytes
     * @param nNumOfBytes number of bytes to convert
     * @return the binhex string
     */
    public static String bytesToBinHex(byte[] data, int nStartPos, int nNumOfBytes)
    {
        StringBuffer sbuf = new StringBuffer();
        sbuf.setLength(nNumOfBytes << 1);
        int nPos = 0;
        for (int nI = 0; nI < nNumOfBytes; nI++)
        {
            sbuf.setCharAt(nPos++, HEXTAB[(data[nI + nStartPos] >> 4) & 0x0f]);
            sbuf.setCharAt(nPos++, HEXTAB[data[nI + nStartPos] & 0x0f]);
        }
        return sbuf.toString();
    }
    /**
     * converts a binhex string back into a byte array (invalid codes will be skipped)
     *
     * @param sBinHex     binhex string
     * @param data        the target array
     * @param nSrcPos     from which character in the string the conversion should begin,
     *                    remember that (nSrcPos modulo 2) should equals 0 normally
     * @param nDstPos     to store the bytes from which position in the array
     * @param nNumOfBytes number of bytes to extract
     * @return number of extracted bytes
     */
    public static int binHexToBytes(String sBinHex, byte[] data, int nSrcPos, int nDstPos, int nNumOfBytes)
    {
        // check for correct ranges
        int nStrLen = sBinHex.length();
        int nAvailBytes = (nStrLen - nSrcPos) >> 1;
        if (nAvailBytes < nNumOfBytes)
        {
            nNumOfBytes = nAvailBytes;
        }
        int nOutputCapacity = data.length - nDstPos;
        if (nNumOfBytes > nOutputCapacity)
        {
            nNumOfBytes = nOutputCapacity;
        }
        // convert now
        int nResult = 0;
        for (int nI = 0; nI < nNumOfBytes; nI++)
        {
            byte bActByte = 0;
            boolean blConvertOK = true;
            for (int nJ = 0; nJ < 2; nJ++)
            {
                bActByte <<= 4;
                char cActChar = sBinHex.charAt(nSrcPos++);
                if ((cActChar >= 'a') && (cActChar <= 'f'))
                {
                    bActByte |= (byte) (cActChar - 'a') + 10;
                } else if ((cActChar >= '0') && (cActChar <= '9'))
                {
                    bActByte |= (byte) (cActChar - '0');
                } else
                {
                    blConvertOK = false;
                }
            }
            if (blConvertOK)
            {
                data[nDstPos++] = bActByte;
                nResult++;
            }
        }
        return nResult;
    }
    /**
     * converts a byte array into an UNICODE string
     *
     * @param data        the byte array
     * @param nStartPos   where to begin the conversion
     * @param nNumOfBytes number of bytes to handle
     * @return the string
     */
    public static String byteArrayToUNCString(byte[] data, int nStartPos, int nNumOfBytes)
    {
        // we need two bytes for every character
        nNumOfBytes &= ~1;
        // enough bytes in the buffer?
        int nAvailCapacity = data.length - nStartPos;
        if (nAvailCapacity < nNumOfBytes)
        {
            nNumOfBytes = nAvailCapacity;
        }
        StringBuffer sbuf = new StringBuffer();
        sbuf.setLength(nNumOfBytes >> 1);
        int nSBufPos = 0;
        while (nNumOfBytes > 0)
        {
            sbuf.setCharAt(nSBufPos++, (char) (((int) data[nStartPos] << 8) | ((int) data[nStartPos + 1] & 0x0ff)));
            nStartPos += 2;
            nNumOfBytes -= 2;
        }
        return sbuf.toString();
    }
    public static long[] marshalByteArray(byte[] raws, boolean hasSignature)
    {
        int remainder = raws.length % 8;
        ByteBuffer rawData = ByteBuffer.wrap(raws);
        rawData.rewind();
        rawData.order(ByteOrder.LITTLE_ENDIAN);
        LongBuffer longBuffer = ((ByteBuffer) rawData.rewind()).asLongBuffer();
        int resultSize = longBuffer.limit() + ((remainder != 0)
                ? 1
                : 0) + (hasSignature
                ? 1
                : 0);
        long[] result = new long[resultSize];
        int i = 0;
        if (hasSignature)
        {
            result[i] = raws.length;
            i++;
        }
        while (longBuffer.hasRemaining())
        {
            result[i] = longBuffer.get();
            i++;
        }
        if (remainder != 0)
        {
            int pos = (i - (hasSignature
                    ? 1
                    : 0)) * 8;
            // int pos = rawData.position();
            byte[] temp = new byte[8];
            for (int j = 0; j < remainder; j++)
            {
                temp[7 - j] = raws[pos + j];
            }
            // System.arraycopy(raws, pos, temp, 0, remainder);
            result[i] = BinConverter.byteArrayToLong(temp, 0);
        }
        return result;
    }
    public static byte[] unmarshalByteArray(long[] raws, boolean hasSignature)
    {
        LongBuffer longBuffer = LongBuffer.wrap(raws);
        int resultBufferSize = (raws.length - (hasSignature
                ? 1
                : 0)) * 8;
        int resultSize = resultBufferSize;
        if (hasSignature)
        {
            resultSize = (int) longBuffer.get();
        }
        ByteBuffer result = ByteBuffer.allocate(resultBufferSize);
        result.order(ByteOrder.LITTLE_ENDIAN);
        while (longBuffer.hasRemaining())
        {
            result.putLong(longBuffer.get());
        }
        if (resultSize == resultBufferSize)
        {
            return result.array();
        }
        byte[] resultData = new byte[resultSize];
        result.position(0);
        result.get(resultData, 0, resultSize);
        return resultData;
    }
    public static long[] marshalCompactByteArray(byte[] raws)
    {
        byte[] compactRaws = new byte[raws.length + 2];
        ByteBuffer bbCompact = ByteBuffer.wrap(compactRaws);
        bbCompact.order(ByteOrder.LITTLE_ENDIAN);
        bbCompact.putShort((short) raws.length);
        bbCompact.put(raws);
        long[] longData = BinConverter.marshalByteArray(compactRaws, false);
        return longData;
    }
    public static byte[] unmarshalCompactByteArray(long[] raws)
    {
        byte[] rawData = BinConverter.unmarshalByteArray(raws, false);
        ByteBuffer bbCompact = ByteBuffer.wrap(rawData);
        bbCompact.order(ByteOrder.LITTLE_ENDIAN);
        short originSize = bbCompact.getShort();
        byte[] rawOriginData = new byte[originSize];
        bbCompact.get(rawOriginData, 0, originSize);
        return rawOriginData;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/Bits.java
New file
@@ -0,0 +1,323 @@
package com.ximple.eofms.util;
//~--- JDK imports ------------------------------------------------------------
import java.nio.ByteOrder;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.misc.VM;
/**
 * Bits
 * User: Ulysses
 * Date: 2007/6/17
 * Time: ¤W¤È 01:16:39
 */
public class Bits
{
    // -- Unsafe access --
    // private static final Unsafe unsafe = Unsafe.getUnsafe();
    // -- Processor and memory-system properties --
    private static ByteOrder byteOrder = null;
    private static int pageSize = -1;
    private static boolean unaligned;
    private static boolean unalignedKnown = false;
    // -- Direct memory management --
    // A user-settable upper limit on the maximum amount of allocatable
    // direct buffer memory. This value may be changed during VM
    // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
    private static volatile long maxMemory = VM.maxDirectMemory();
    private static volatile long reservedMemory = 0;
    private static boolean memoryLimitSet = false;
    private Bits()
    {
    }
    // -- Swapping --
    public static short swap(short x)
    {
        return (short) ((x << 8) | ((x >> 8) & 0xff));
    }
    public static char swap(char x)
    {
        return (char) ((x << 8) | ((x >> 8) & 0xff));
    }
    public static int swap(int x)
    {
        return (int) ((swap((short) x) << 16) | (swap((short) (x >> 16)) & 0xffff));
    }
    public static long swap(long x)
    {
        return (long) (((long) swap((int) (x)) << 32) | ((long) swap((int) (x >> 32)) & 0xffffffffL));
    }
    // -- get/put char --
    static private char makeChar(byte b1, byte b0)
    {
        return (char) ((b1 << 8) | (b0 & 0xff));
    }
    private static byte char1(char x)
    {
        return (byte) (x >> 8);
    }
    private static byte char0(char x)
    {
        return (byte) (x >> 0);
    }
    // --get/put short--
    public static short makeShort(byte b1, byte b0)
    {
        return (short) ((b1 << 8) | (b0 & 0xff));
    }
    private static byte short1(short x)
    {
        return (byte) (x >> 8);
    }
    public static byte short0(short x)
    {
        return (byte) (x >> 0);
    }
    // -- get/put int --
    public static int makeInt(byte b3, byte b2, byte b1, byte b0)
    {
        return (int) ((((b3 & 0xff) << 24) | ((b2 & 0xff) << 16) | ((b1 & 0xff) << 8) | ((b0 & 0xff) << 0)));
    }
    public static int makeInt(short hiword, short loword)
    {
        return ((hiword & 0xffff) << 16) + (loword & 0xffff);
    }
    public static short getHiShort(int qwValue)
    {
        return ((short) (qwValue >>> 16));
    }
    public static short getLoShort(int qwValue)
    {
        return ((short) (qwValue & 0xFFFF));
    }
    public static byte int3(int x)
    {
        return (byte) (x >> 24);
    }
    public static byte int2(int x)
    {
        return (byte) (x >> 16);
    }
    private static byte int1(int x)
    {
        return (byte) (x >> 8);
    }
    private static byte int0(int x)
    {
        return (byte) (x >> 0);
    }
    // -- get/put long --
    public static long makeLong(byte b7, byte b6, byte b5, byte b4, byte b3, byte b2, byte b1, byte b0)
    {
        return ((((long) b7 & 0xff) << 56) | (((long) b6 & 0xff) << 48) | (((long) b5 & 0xff) << 40) | (((long) b4 & 0xff) << 32)
                | (((long) b3 & 0xff) << 24) | (((long) b2 & 0xff) << 16) | (((long) b1 & 0xff) << 8)
                | (((long) b0 & 0xff) << 0));
    }
    public static long makeLong(int LoValue, int HiValue)
    {
        return (((long) HiValue & 0xFFFFFFFF) << 32) + (((long) LoValue) & 0xFFFFFFFF);
    }
    public static int getHiInt(long qwValue)
    {
        return ((int) (qwValue >>> 32));
    }
    public static int getLoInt(long qwValue)
    {
        return ((int) (qwValue & 0xFFFFFFFF));
    }
    private static byte long7(long x)
    {
        return (byte) (x >> 56);
    }
    private static byte long6(long x)
    {
        return (byte) (x >> 48);
    }
    private static byte long5(long x)
    {
        return (byte) (x >> 40);
    }
    private static byte long4(long x)
    {
        return (byte) (x >> 32);
    }
    private static byte long3(long x)
    {
        return (byte) (x >> 24);
    }
    private static byte long2(long x)
    {
        return (byte) (x >> 16);
    }
    private static byte long1(long x)
    {
        return (byte) (x >> 8);
    }
    private static byte long0(long x)
    {
        return (byte) (x >> 0);
    }
    // -- get/put float --
    // -- get/put double --
    /*
    private static byte _get(long a)
    {
        return unsafe.getByte(a);
    }
    private static void _put(long a, byte b)
    {
        unsafe.putByte(a, b);
    }
    static Unsafe unsafe()
    {
        return unsafe;
    }
    static ByteOrder byteOrder()
    {
        if (byteOrder != null)
        {
            return byteOrder;
        }
        long a = unsafe.allocateMemory(8);
        try
        {
            unsafe.putLong(a, 0x0102030405060708L);
            byte b = unsafe.getByte(a);
            switch (b)
            {
            case 0x01 :
                byteOrder = ByteOrder.BIG_ENDIAN;
                break;
            case 0x08 :
                byteOrder = ByteOrder.LITTLE_ENDIAN;
                break;
            default :
                throw new Error("Unknown byte order");
            }
        } finally
        {
            unsafe.freeMemory(a);
        }
        return byteOrder;
    }
    */
    static boolean unaligned()
    {
        if (unalignedKnown)
        {
            return unaligned;
        }
        PrivilegedAction pa = new sun.security.action.GetPropertyAction("os.arch");
        String arch = (String) AccessController.doPrivileged(pa);
        unaligned = arch.equals("i386") || arch.equals("x86");
        unalignedKnown = true;
        return unaligned;
    }
    // These methods should be called whenever direct memory is allocated or
    //  freed. They allow the user to control the amount of direct memory
    // which a process may access. All sizes are specified in bytes.
    static void reserveMemory(long size)
    {
        synchronized (Bits.class)
        {
            if (!memoryLimitSet && VM.isBooted())
            {
                maxMemory = VM.maxDirectMemory();
                memoryLimitSet = true;
            }
            if (size <= maxMemory - reservedMemory)
            {
                reservedMemory += size;
                return;
            }
        }
        System.gc();
        try
        {
            Thread.sleep(100);
        } catch (InterruptedException x)
        {
            // Restore interrupt status
            Thread.currentThread().interrupt();
        }
        synchronized (Bits.class)
        {
            if (reservedMemory + size > maxMemory)
            {
                throw new OutOfMemoryError("Direct buffer memory");
            }
            reservedMemory += size;
        }
    }
    static synchronized void unreserveMemory(long size)
    {
        if (reservedMemory > 0)
        {
            reservedMemory -= size;
            assert (reservedMemory > -1);
        }
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/ByteArrayCompressor.java
New file
@@ -0,0 +1,97 @@
package com.ximple.eofms.util;
//~--- JDK imports ------------------------------------------------------------
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
/**
 * ByteArrayCompressor
 * User: Ulysses
 * Date: 2007/6/15
 * Time: ¤U¤È 02:21:00
 * To change this template use File | Settings | File Templates.
 */
public final class ByteArrayCompressor
{
    public static byte[] decompressByteArray(byte[] raw)
    {
        // Create the decompressor and give it the data to compress
        Inflater decompressor = new Inflater();
        decompressor.setInput(raw);
        // Create an expandable byte array to hold the decompressed data
        ByteArrayOutputStream bos = new ByteArrayOutputStream(raw.length);
        // Decompress the data
        byte[] buf = new byte[1024];
        while (!decompressor.finished())
        {
            try
            {
                int count = decompressor.inflate(buf);
                bos.write(buf, 0, count);
            } catch (DataFormatException e)
            {
            }
        }
        try
        {
            bos.close();
        } catch (IOException e)
        {
        }
        // Get the decompressed data
        byte[] decompressedData = bos.toByteArray();
        return decompressedData;
    }
    public static byte[] compressByteArray(byte[] raw)
    {
        // Create the compressor with highest level of compression
        Deflater compressor = new Deflater();
        compressor.setLevel(Deflater.BEST_SPEED);
        // Give the compressor the data to compress
        compressor.setInput(raw);
        compressor.finish();
        // Create an expandable byte array to hold the compressed data.
        // You cannot use an array that's the same size as the orginal because
        // there is no guarantee that the compressed data will be smaller than
        // the uncompressed data.
        ByteArrayOutputStream bos = new ByteArrayOutputStream(raw.length);
        // Compress the data
        byte[] buf = new byte[1024];
        while (!compressor.finished())
        {
            int count = compressor.deflate(buf);
            bos.write(buf, 0, count);
        }
        try
        {
            bos.close();
        } catch (IOException e)
        {
        }
        // Get the compressed data
        byte[] compressedData = bos.toByteArray();
        return compressedData;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/ColorTableMapping.java
New file
@@ -0,0 +1,12 @@
package com.ximple.eofms.util;
import java.awt.Color;
import java.util.List;
public interface ColorTableMapping
{
    boolean contain(Color color);
    List findId(Color color);
    Color getColor(int value);
    String getColorCode(int i);
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/DefaultColorTable.java
New file
@@ -0,0 +1,363 @@
package com.ximple.eofms.util;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
public class DefaultColorTable implements ColorTableMapping
{
    private static DefaultColorTable _instance  = null;
    public static ColorTableMapping getInstance()
    {
        if (_instance == null)
        {
            _instance = new DefaultColorTable();
        }
        return _instance;
    }
    private ArrayList<Color> colortable = null;
    private DefaultColorTable()
    {
        initializeColorTable();
    }
    private void initializeColorTable()
    {
        if (colortable != null)
        {
            return;
        }
        colortable = new ArrayList<Color>(255);
        colortable.add(0, new Color(255, 255, 255));
        colortable.add(1, new Color(0, 0, 255));
        colortable.add(2, new Color(0, 255, 0));
        colortable.add(3, new Color(255, 0, 0));
        colortable.add(4, new Color(255, 255, 0));
        colortable.add(5, new Color(255, 0, 255));
        colortable.add(6, new Color(255, 127, 0));
        colortable.add(7, new Color(0, 255, 255));
        colortable.add(8, new Color(64, 64, 64));
        colortable.add(9, new Color(192, 192, 192));
        colortable.add(10, new Color(254, 0, 96));
        colortable.add(11, new Color(160, 224, 0));
        colortable.add(12, new Color(0, 254, 160));
        colortable.add(13, new Color(128, 0, 160));
        colortable.add(14, new Color(176, 176, 176));
        colortable.add(15, new Color(0, 240, 240));
        colortable.add(16, new Color(240, 240, 240));
        colortable.add(17, new Color(0, 0, 240));
        colortable.add(18, new Color(0, 240, 0));
        colortable.add(19, new Color(240, 0, 0));
        colortable.add(20, new Color(240, 240, 0));
        colortable.add(21, new Color(240, 0, 240));
        colortable.add(22, new Color(240, 122, 0));
        colortable.add(23, new Color(0, 240, 240));
        colortable.add(24, new Color(240, 240, 240));
        colortable.add(25, new Color(0, 0, 240));
        colortable.add(26, new Color(0, 240, 0));
        colortable.add(27, new Color(240, 0, 0));
        colortable.add(28, new Color(240, 240, 0));
        colortable.add(29, new Color(240, 0, 240));
        colortable.add(30, new Color(240, 122, 0));
        colortable.add(31, new Color(0, 225, 225));
        colortable.add(32, new Color(225, 225, 225));
        colortable.add(33, new Color(0, 0, 225));
        colortable.add(34, new Color(0, 225, 0));
        colortable.add(35, new Color(225, 0, 0));
        colortable.add(36, new Color(225, 225, 0));
        colortable.add(37, new Color(225, 0, 225));
        colortable.add(38, new Color(225, 117, 0));
        colortable.add(39, new Color(0, 225, 225));
        colortable.add(40, new Color(225, 225, 225));
        colortable.add(41, new Color(0, 0, 225));
        colortable.add(42, new Color(0, 225, 0));
        colortable.add(43, new Color(225, 0, 0));
        colortable.add(44, new Color(225, 225, 0));
        colortable.add(45, new Color(225, 0, 225));
        colortable.add(46, new Color(225, 117, 0));
        colortable.add(47, new Color(0, 210, 210));
        colortable.add(48, new Color(210, 210, 210));
        colortable.add(49, new Color(0, 0, 210));
        colortable.add(50, new Color(0, 210, 0));
        colortable.add(51, new Color(210, 0, 0));
        colortable.add(52, new Color(210, 210, 0));
        colortable.add(53, new Color(210, 0, 210));
        colortable.add(54, new Color(210, 112, 0));
        colortable.add(55, new Color(0, 210, 210));
        colortable.add(56, new Color(210, 210, 210));
        colortable.add(57, new Color(0, 0, 210));
        colortable.add(58, new Color(0, 210, 0));
        colortable.add(59, new Color(210, 0, 0));
        colortable.add(60, new Color(210, 210, 0));
        colortable.add(61, new Color(210, 0, 210));
        colortable.add(62, new Color(210, 112, 0));
        colortable.add(63, new Color(0, 195, 195));
        colortable.add(64, new Color(195, 195, 195));
        colortable.add(65, new Color(0, 0, 195));
        colortable.add(66, new Color(0, 195, 0));
        colortable.add(67, new Color(195, 0, 0));
        colortable.add(68, new Color(195, 195, 0));
        colortable.add(69, new Color(195, 0, 195));
        colortable.add(70, new Color(195, 107, 0));
        colortable.add(71, new Color(0, 195, 195));
        colortable.add(72, new Color(195, 195, 195));
        colortable.add(73, new Color(0, 0, 195));
        colortable.add(74, new Color(0, 195, 0));
        colortable.add(75, new Color(195, 0, 0));
        colortable.add(76, new Color(195, 195, 0));
        colortable.add(77, new Color(195, 0, 195));
        colortable.add(78, new Color(195, 107, 0));
        colortable.add(79, new Color(0, 180, 180));
        colortable.add(80, new Color(180, 180, 180));
        colortable.add(81, new Color(0, 0, 180));
        colortable.add(82, new Color(0, 180, 0));
        colortable.add(83, new Color(180, 0, 0));
        colortable.add(84, new Color(180, 180, 0));
        colortable.add(85, new Color(180, 0, 180));
        colortable.add(86, new Color(180, 102, 0));
        colortable.add(87, new Color(0, 180, 180));
        colortable.add(88, new Color(180, 180, 180));
        colortable.add(89, new Color(0, 0, 180));
        colortable.add(90, new Color(0, 180, 0));
        colortable.add(91, new Color(180, 0, 0));
        colortable.add(92, new Color(180, 180, 0));
        colortable.add(93, new Color(180, 0, 180));
        colortable.add(94, new Color(180, 102, 0));
        colortable.add(95, new Color(0, 165, 165));
        colortable.add(96, new Color(165, 165, 165));
        colortable.add(97, new Color(0, 0, 165));
        colortable.add(98, new Color(0, 165, 0));
        colortable.add(99, new Color(165, 0, 0));
        colortable.add(100, new Color(165, 165, 0));
        colortable.add(101, new Color(165, 0, 165));
        colortable.add(102, new Color(165, 97, 0));
        colortable.add(103, new Color(0, 165, 165));
        colortable.add(104, new Color(165, 165, 165));
        colortable.add(105, new Color(0, 0, 165));
        colortable.add(106, new Color(0, 165, 0));
        colortable.add(107, new Color(165, 0, 0));
        colortable.add(108, new Color(165, 165, 0));
        colortable.add(109, new Color(165, 0, 165));
        colortable.add(110, new Color(165, 97, 0));
        colortable.add(111, new Color(0, 150, 150));
        colortable.add(112, new Color(150, 150, 150));
        colortable.add(113, new Color(0, 0, 150));
        colortable.add(114, new Color(0, 150, 0));
        colortable.add(115, new Color(150, 0, 0));
        colortable.add(116, new Color(150, 150, 0));
        colortable.add(117, new Color(150, 0, 150));
        colortable.add(118, new Color(150, 92, 0));
        colortable.add(119, new Color(0, 150, 150));
        colortable.add(120, new Color(150, 150, 150));
        colortable.add(121, new Color(0, 0, 150));
        colortable.add(122, new Color(0, 150, 0));
        colortable.add(123, new Color(150, 0, 0));
        colortable.add(124, new Color(150, 150, 0));
        colortable.add(125, new Color(150, 0, 150));
        colortable.add(126, new Color(150, 92, 0));
        colortable.add(127, new Color(0, 135, 135));
        colortable.add(128, new Color(135, 135, 135));
        colortable.add(129, new Color(0, 0, 135));
        colortable.add(130, new Color(0, 135, 0));
        colortable.add(131, new Color(135, 0, 0));
        colortable.add(132, new Color(135, 135, 0));
        colortable.add(133, new Color(135, 0, 135));
        colortable.add(134, new Color(135, 87, 0));
        colortable.add(135, new Color(0, 135, 135));
        colortable.add(136, new Color(135, 135, 135));
        colortable.add(137, new Color(0, 0, 135));
        colortable.add(138, new Color(0, 135, 0));
        colortable.add(139, new Color(135, 0, 0));
        colortable.add(140, new Color(135, 135, 0));
        colortable.add(141, new Color(135, 0, 135));
        colortable.add(142, new Color(135, 87, 0));
        colortable.add(143, new Color(0, 120, 120));
        colortable.add(144, new Color(120, 120, 120));
        colortable.add(145, new Color(0, 0, 120));
        colortable.add(146, new Color(0, 120, 0));
        colortable.add(147, new Color(120, 0, 0));
        colortable.add(148, new Color(120, 120, 0));
        colortable.add(149, new Color(120, 0, 120));
        colortable.add(150, new Color(120, 82, 0));
        colortable.add(151, new Color(0, 120, 120));
        colortable.add(152, new Color(120, 120, 120));
        colortable.add(153, new Color(0, 0, 120));
        colortable.add(154, new Color(0, 120, 0));
        colortable.add(155, new Color(120, 0, 0));
        colortable.add(156, new Color(120, 120, 0));
        colortable.add(157, new Color(120, 0, 120));
        colortable.add(158, new Color(120, 82, 0));
        colortable.add(159, new Color(0, 105, 105));
        colortable.add(160, new Color(105, 105, 105));
        colortable.add(161, new Color(0, 0, 105));
        colortable.add(162, new Color(0, 105, 0));
        colortable.add(163, new Color(105, 0, 0));
        colortable.add(164, new Color(105, 105, 0));
        colortable.add(165, new Color(105, 0, 105));
        colortable.add(166, new Color(105, 77, 0));
        colortable.add(167, new Color(0, 105, 105));
        colortable.add(168, new Color(105, 105, 105));
        colortable.add(169, new Color(0, 0, 105));
        colortable.add(170, new Color(0, 105, 0));
        colortable.add(171, new Color(105, 0, 0));
        colortable.add(172, new Color(105, 105, 0));
        colortable.add(173, new Color(105, 0, 105));
        colortable.add(174, new Color(105, 77, 0));
        colortable.add(175, new Color(0, 90, 90));
        colortable.add(176, new Color(90, 90, 90));
        colortable.add(177, new Color(0, 0, 90));
        colortable.add(178, new Color(0, 90, 0));
        colortable.add(179, new Color(90, 0, 0));
        colortable.add(180, new Color(90, 90, 0));
        colortable.add(181, new Color(90, 0, 90));
        colortable.add(182, new Color(90, 72, 0));
        colortable.add(183, new Color(0, 90, 90));
        colortable.add(184, new Color(90, 90, 90));
        colortable.add(185, new Color(0, 0, 90));
        colortable.add(186, new Color(0, 90, 0));
        colortable.add(187, new Color(90, 0, 0));
        colortable.add(188, new Color(90, 90, 0));
        colortable.add(189, new Color(90, 0, 90));
        colortable.add(190, new Color(90, 72, 0));
        colortable.add(191, new Color(0, 75, 75));
        colortable.add(192, new Color(75, 75, 75));
        colortable.add(193, new Color(0, 0, 75));
        colortable.add(194, new Color(0, 75, 0));
        colortable.add(195, new Color(75, 0, 0));
        colortable.add(196, new Color(75, 75, 0));
        colortable.add(197, new Color(75, 0, 75));
        colortable.add(198, new Color(75, 67, 0));
        colortable.add(199, new Color(0, 75, 75));
        colortable.add(200, new Color(75, 75, 75));
        colortable.add(201, new Color(0, 0, 75));
        colortable.add(202, new Color(0, 75, 0));
        colortable.add(203, new Color(75, 0, 0));
        colortable.add(204, new Color(75, 75, 0));
        colortable.add(205, new Color(75, 0, 75));
        colortable.add(206, new Color(75, 67, 0));
        colortable.add(207, new Color(0, 60, 60));
        colortable.add(208, new Color(60, 60, 60));
        colortable.add(209, new Color(0, 0, 60));
        colortable.add(210, new Color(0, 60, 0));
        colortable.add(211, new Color(60, 0, 0));
        colortable.add(212, new Color(60, 60, 0));
        colortable.add(213, new Color(60, 0, 60));
        colortable.add(214, new Color(60, 62, 0));
        colortable.add(215, new Color(0, 60, 60));
        colortable.add(216, new Color(60, 60, 60));
        colortable.add(217, new Color(0, 0, 60));
        colortable.add(218, new Color(0, 60, 0));
        colortable.add(219, new Color(60, 0, 0));
        colortable.add(220, new Color(60, 60, 0));
        colortable.add(221, new Color(60, 0, 60));
        colortable.add(222, new Color(60, 62, 0));
        colortable.add(223, new Color(0, 45, 45));
        colortable.add(224, new Color(45, 45, 45));
        colortable.add(225, new Color(0, 0, 45));
        colortable.add(226, new Color(0, 45, 0));
        colortable.add(227, new Color(45, 0, 0));
        colortable.add(228, new Color(45, 45, 0));
        colortable.add(229, new Color(45, 0, 45));
        colortable.add(230, new Color(45, 57, 0));
        colortable.add(231, new Color(0, 45, 45));
        colortable.add(232, new Color(45, 45, 45));
        colortable.add(233, new Color(0, 0, 45));
        colortable.add(234, new Color(0, 45, 0));
        colortable.add(235, new Color(45, 0, 0));
        colortable.add(236, new Color(45, 45, 0));
        colortable.add(237, new Color(45, 0, 45));
        colortable.add(238, new Color(45, 57, 0));
        colortable.add(239, new Color(0, 30, 30));
        colortable.add(240, new Color(30, 30, 30));
        colortable.add(241, new Color(0, 0, 30));
        colortable.add(242, new Color(0, 30, 0));
        colortable.add(243, new Color(30, 0, 0));
        colortable.add(244, new Color(30, 30, 0));
        colortable.add(245, new Color(30, 0, 30));
        colortable.add(246, new Color(30, 52, 0));
        colortable.add(247, new Color(0, 30, 30));
        colortable.add(248, new Color(30, 30, 30));
        colortable.add(249, new Color(0, 0, 30));
        colortable.add(250, new Color(0, 30, 0));
        colortable.add(251, new Color(30, 0, 0));
        colortable.add(252, new Color(30, 30, 0));
        colortable.add(253, new Color(30, 0, 30));
        colortable.add(254, new Color(30, 52, 0));
    }
    public List findId(Color color)
    {
        ArrayList<Integer> codelist = new ArrayList<Integer>();
        for (int i = 0; i < colortable.size(); i++)
        {
            Color colorDef = colortable.get(i);
            if (colorDef.equals(color))
            {
                codelist.add(i);
            }
        }
        return codelist;
    }
    public Color getColor(int i)
    {
        return colortable.get(i);
    }
    public String getColorCode(int i)
    {
        Color color = colortable.get(i);
        if (!color.equals(Color.WHITE))
            return colorToString(colortable.get(i));
        return colorToString(Color.GRAY);
    }
    public boolean contain(Color color)
    {
        for (Color colorDef : colortable)
        {
            if (colorDef.equals(color))
            {
                return true;
            }
        }
        return false;
    }
    private static String colorToString(Color c) {
        char[] buf = new char[7];
        buf[0] = '#';
        String s = Integer.toHexString(c.getRed());
        if (s.length() == 1) {
            buf[1] = '0';
            buf[2] = s.charAt(0);
        }
        else {
            buf[1] = s.charAt(0);
            buf[2] = s.charAt(1);
        }
        s = Integer.toHexString(c.getGreen());
        if (s.length() == 1) {
            buf[3] = '0';
            buf[4] = s.charAt(0);
        }
        else {
            buf[3] = s.charAt(0);
            buf[4] = s.charAt(1);
        }
        s = Integer.toHexString(c.getBlue());
        if (s.length() == 1) {
            buf[5] = '0';
            buf[6] = s.charAt(0);
        }
        else {
            buf[5] = s.charAt(0);
            buf[6] = s.charAt(1);
        }
        return String.valueOf(buf);
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/GeomUtil.java
New file
@@ -0,0 +1,30 @@
package com.ximple.eofms.util;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
/**
 * Created by IntelliJ IDEA.
 * User: Ulysses
 * Date: 2007/6/15
 * Time: ¤W¤È 01:20:20
 * To change this template use File | Settings | File Templates.
 */
public final class GeomUtil
{
    public static double convertLogicalValue(double value)
    {
        return value / 1000.0 + 2147483.648;
    }
    public static Coordinate convertLogicalCooridate(Coordinate value)
    {
        return new Coordinate(convertLogicalValue(value.x), convertLogicalValue(value.y), convertLogicalValue(value.z));
    }
    public static Envelope convertLogicalEnvelope(Envelope value)
    {
        return new Envelope(convertLogicalValue(value.getMinX()), convertLogicalValue(value.getMaxX()),
                            convertLogicalValue(value.getMinY()), convertLogicalValue(value.getMaxY()));
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/LangUtil.java
New file
@@ -0,0 +1,104 @@
package com.ximple.eofms.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.vividsolutions.jts.util.Assert;
/**
 * Created by IntelliJ IDEA.
 * User: Ulysses
 * Date: 2007/6/15
 * Time: ¤W¤È 01:21:25
 * To change this template use File | Settings | File Templates.
 */
public class LangUtil
{
    private static Map primitiveToWrapperMap = new HashMap()
    {
        {
            put(byte.class, Byte.class);
            put(char.class, Character.class);
            put(short.class, Short.class);
            put(int.class, Integer.class);
            put(long.class, Long.class);
            put(float.class, Float.class);
            put(double.class, Double.class);
            put(boolean.class, Boolean.class);
        }
    };
    public static String emptyStringIfNull(String s)
    {
        return (s == null) ? "" : s;
    }
    /**
     * Useful because an expression used to generate o need only be
     * evaluated once.
     */
    public static Object ifNull(Object o, Object alternative)
    {
        return (o == null) ? alternative : o;
    }
    public static Object ifNotNull(Object o, Object alternative)
    {
        return (o != null) ? alternative : o;
    }
    public static Class toPrimitiveWrapperClass(Class primitiveClass)
    {
        return (Class) primitiveToWrapperMap.get(primitiveClass);
    }
    public static boolean isPrimitive(Class c)
    {
        return primitiveToWrapperMap.containsKey(c);
    }
    public static boolean bothNullOrEqual(Object a, Object b)
    {
        return (a == null && b == null) || (a != null && b != null && a.equals(b));
    }
    public static Object newInstance(Class c)
    {
        try
        {
            return c.newInstance();
        } catch (Exception e)
        {
            Assert.shouldNeverReachHere(e.toString());
            return null;
        }
    }
    public static Collection classesAndInterfaces(Class c)
    {
        ArrayList classesAndInterfaces = new ArrayList();
        classesAndInterfaces.add(c);
        superclasses(c, classesAndInterfaces);
        for (Iterator i = new ArrayList(classesAndInterfaces).iterator(); i.hasNext();)
        {
            Class x = (Class) i.next();
            classesAndInterfaces.addAll(Arrays.asList(x.getInterfaces()));
        }
        return classesAndInterfaces;
    }
    private static void superclasses(Class c, Collection results)
    {
        if (c.getSuperclass() == null)
        {
            return;
        }
        results.add(c.getSuperclass());
        superclasses(c.getSuperclass(), results);
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/PrintfFormat.java
New file
Diff too large
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/StringUtils.java
New file
@@ -0,0 +1,2923 @@
package com.ximple.eofms.util;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collection;
import java.util.Locale;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharacterCodingException;
import java.nio.CharBuffer;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.lang.reflect.Array;
import java.text.BreakIterator;
public abstract class StringUtils
{
    public static String ENCODING_US_ASCII = "US-ASCII";
    public static String ENCODING_ISO_8859_1 = "ISO-8859-1";
    public static String ENCODING_ISO_8859_2 = "ISO-8859-2";
    public static String ENCODING_ISO_8859_5 = "ISO-8859-5";
    public static String ENCODING_UTF_8 = "UTF-8";
    public static String ENCODING_UTF_16BE = "UTF-16BE";
    public static String ENCODING_UTF_16LE = "UTF-16LE";
    public static String ENCODING_UTF_16 = "UTF-16";
    public static Charset CHARSET_US_ASCII = Charset.forName(StringUtils.ENCODING_US_ASCII);
    public static final Pattern BBCODE_COLOR = Pattern.compile("\\[color\\s*=\\s*([#\\w]*)\\s*\\]", Pattern.CASE_INSENSITIVE);
    public static final Pattern BBCODE_SIZE = Pattern.compile("\\[size\\s*=\\s*([+\\-]?[0-9]*)\\s*\\]", Pattern.CASE_INSENSITIVE);
    public static final Pattern BBCODE_URL_SHORT = Pattern.compile("\\[url\\]\\s*([^\\s]*)\\s*\\[\\/url\\]", Pattern.CASE_INSENSITIVE);
    public static final Pattern BBCODE_URL_LONG = Pattern.compile("\\[url=([^\\[]*)\\]([^\\[]*)\\[/url\\]", Pattern.CASE_INSENSITIVE);
    public static final Pattern BBCODE_IMG = Pattern.compile("\\[img\\]\\s*([^\\s]*)\\s*\\[\\/img\\]", Pattern.CASE_INSENSITIVE);
    public static final Pattern BBCODE_QUOTE_LONG = Pattern.compile("\\[quote=([^\\]]+\\]*)\\]", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
    public static final Pattern BBCODE_BAREURL = Pattern.compile("(?:[^\"'=>\\]]|^)((?:http|ftp)s?://(?:%[\\p{Digit}A-Fa-f][\\p{Digit}A-Fa-f]|[\\-_\\.!~*';\\|/?:@#&=\\+$,\\p{Alnum}])+)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
    private static final Map<Character, String> AGGRESSIVE_HTML_ENCODE_MAP = new HashMap<Character, String>();
    private static final Map<Character, String> DEFENSIVE_HTML_ENCODE_MAP = new HashMap<Character, String>();
    private static final Map<Character, String> XML_ENCODE_MAP = new HashMap<Character, String>();
    private static final Map<Character, String> STRING_ENCODE_MAP = new HashMap<Character, String>();
    private static final Map<Character, String> SQL_ENCODE_MAP = new HashMap<Character, String>();
    private static final Map<Character, String> LATEX_ENCODE_MAP = new HashMap<Character, String>();
    private static final Map<String, Character>        HTML_DECODE_MAP = new HashMap<String, Character>();
    private static final HtmlEncoderFallbackHandler HTML_ENCODER_FALLBACK = new HtmlEncoderFallbackHandler();
    static
    {
        // Html encoding mapping according to the HTML 4.0 spec
        // http://www.w3.org/TR/REC-html40/sgml/entities.html
        // Special characters for HTML
        AGGRESSIVE_HTML_ENCODE_MAP.put('\u0026',"&amp;");
        AGGRESSIVE_HTML_ENCODE_MAP.put('\u003C',"&lt;");
        AGGRESSIVE_HTML_ENCODE_MAP.put('\u003E',"&gt;");
        AGGRESSIVE_HTML_ENCODE_MAP.put('\u0022',"&quot;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0152',"&OElig;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0153',"&oelig;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0160',"&Scaron;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0161',"&scaron;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0178',"&Yuml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u02C6',"&circ;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u02DC',"&tilde;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2002',"&ensp;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2003',"&emsp;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2009',"&thinsp;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u200C',"&zwnj;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u200D',"&zwj;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u200E',"&lrm;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u200F',"&rlm;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2013',"&ndash;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2014',"&mdash;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2018',"&lsquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2019',"&rsquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u201A',"&sbquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u201C',"&ldquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u201D',"&rdquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u201E',"&bdquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2020',"&dagger;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2021',"&Dagger;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2030',"&permil;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2039',"&lsaquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u203A',"&rsaquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u20AC',"&euro;");
        // Character entity references for ISO 8859-1 characters
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A0',"&nbsp;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A1',"&iexcl;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A2',"&cent;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A3',"&pound;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A4',"&curren;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A5',"&yen;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A6',"&brvbar;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A7',"&sect;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A8',"&uml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00A9',"&copy;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00AA',"&ordf;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00AB',"&laquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00AC',"&not;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00AD',"&shy;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00AE',"&reg;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00AF',"&macr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B0',"&deg;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B1',"&plusmn;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B2',"&sup2;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B3',"&sup3;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B4',"&acute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B5',"&micro;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B6',"&para;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B7',"&middot;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B8',"&cedil;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00B9',"&sup1;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00BA',"&ordm;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00BB',"&raquo;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00BC',"&frac14;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00BD',"&frac12;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00BE',"&frac34;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00BF',"&iquest;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C0',"&Agrave;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C1',"&Aacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C2',"&Acirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C3',"&Atilde;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C4',"&Auml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C5',"&Aring;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C6',"&AElig;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C7',"&Ccedil;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C8',"&Egrave;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00C9',"&Eacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00CA',"&Ecirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00CB',"&Euml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00CC',"&Igrave;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00CD',"&Iacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00CE',"&Icirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00CF',"&Iuml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D0',"&ETH;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D1',"&Ntilde;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D2',"&Ograve;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D3',"&Oacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D4',"&Ocirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D5',"&Otilde;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D6',"&Ouml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D7',"&times;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D8',"&Oslash;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00D9',"&Ugrave;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00DA',"&Uacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00DB',"&Ucirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00DC',"&Uuml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00DD',"&Yacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00DE',"&THORN;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00DF',"&szlig;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E0',"&agrave;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E1',"&aacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E2',"&acirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E3',"&atilde;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E4',"&auml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E5',"&aring;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E6',"&aelig;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E7',"&ccedil;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E8',"&egrave;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00E9',"&eacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00EA',"&ecirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00EB',"&euml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00EC',"&igrave;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00ED',"&iacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00EE',"&icirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00EF',"&iuml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F0',"&eth;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F1',"&ntilde;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F2',"&ograve;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F3',"&oacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F4',"&ocirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F5',"&otilde;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F6',"&ouml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F7',"&divide;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F8',"&oslash;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00F9',"&ugrave;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00FA',"&uacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00FB',"&ucirc;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00FC',"&uuml;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00FD',"&yacute;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00FE',"&thorn;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u00FF',"&yuml;");
        // Mathematical, Greek and Symbolic characters for HTML
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0192',"&fnof;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0391',"&Alpha;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0392',"&Beta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0393',"&Gamma;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0394',"&Delta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0395',"&Epsilon;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0396',"&Zeta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0397',"&Eta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0398',"&Theta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u0399',"&Iota;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u039A',"&Kappa;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u039B',"&Lambda;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u039C',"&Mu;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u039D',"&Nu;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u039E',"&Xi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u039F',"&Omicron;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03A0',"&Pi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03A1',"&Rho;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03A3',"&Sigma;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03A4',"&Tau;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03A5',"&Upsilon;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03A6',"&Phi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03A7',"&Chi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03A8',"&Psi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03A9',"&Omega;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03B1',"&alpha;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03B2',"&beta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03B3',"&gamma;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03B4',"&delta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03B5',"&epsilon;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03B6',"&zeta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03B7',"&eta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03B8',"&theta;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03B9',"&iota;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03BA',"&kappa;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03BB',"&lambda;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03BC',"&mu;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03BD',"&nu;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03BE',"&xi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03BF',"&omicron;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C0',"&pi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C1',"&rho;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C2',"&sigmaf;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C3',"&sigma;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C4',"&tau;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C5',"&upsilon;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C6',"&phi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C7',"&chi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C8',"&psi;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03C9',"&omega;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03D1',"&thetasym;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03D2',"&upsih;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u03D6',"&piv;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2022',"&bull;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2026',"&hellip;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2032',"&prime;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2033',"&Prime;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u203E',"&oline;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2044',"&frasl;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2118',"&weierp;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2111',"&image;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u211C',"&real;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2122',"&trade;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2135',"&alefsym;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2190',"&larr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2191',"&uarr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2192',"&rarr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2193',"&darr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2194',"&harr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u21B5',"&crarr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u21D0',"&lArr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u21D1',"&uArr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u21D2',"&rArr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u21D3',"&dArr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u21D4',"&hArr;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2200',"&forall;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2202',"&part;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2203',"&exist;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2205',"&empty;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2207',"&nabla;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2208',"&isin;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2209',"&notin;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u220B',"&ni;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u220F',"&prod;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2211',"&sum;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2212',"&minus;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2217',"&lowast;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u221A',"&radic;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u221D',"&prop;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u221E',"&infin;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2220',"&ang;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2227',"&and;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2228',"&or;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2229',"&cap;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u222A',"&cup;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u222B',"&int;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2234',"&there4;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u223C',"&sim;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2245',"&cong;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2248',"&asymp;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2260',"&ne;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2261',"&equiv;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2264',"&le;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2265',"&ge;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2282',"&sub;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2283',"&sup;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2284',"&nsub;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2286',"&sube;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2287',"&supe;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2295',"&oplus;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2297',"&otimes;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u22A5',"&perp;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u22C5',"&sdot;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2308',"&lceil;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2309',"&rceil;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u230A',"&lfloor;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u230B',"&rfloor;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2329',"&lang;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u232A',"&rang;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u25CA',"&loz;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2660',"&spades;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2663',"&clubs;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2665',"&hearts;");
        DEFENSIVE_HTML_ENCODE_MAP.put('\u2666',"&diams;");
        Set<Map.Entry<Character, String>> aggresive_entries = AGGRESSIVE_HTML_ENCODE_MAP.entrySet();
        for (Map.Entry<Character, String> entry : aggresive_entries)
        {
            HTML_DECODE_MAP.put(entry.getValue(), entry.getKey());
        }
        Set<Map.Entry<Character, String>> defensive_entries = DEFENSIVE_HTML_ENCODE_MAP.entrySet();
        for (Map.Entry<Character, String> entry : defensive_entries)
        {
            HTML_DECODE_MAP.put(entry.getValue(), entry.getKey());
        }
        XML_ENCODE_MAP.put('\u0026',"&amp;");
        XML_ENCODE_MAP.put('\'',"&apos;");
        XML_ENCODE_MAP.put('\u0022',"&quot;");
        XML_ENCODE_MAP.put('\u003C',"&lt;");
        XML_ENCODE_MAP.put('\u003E',"&gt;");
        SQL_ENCODE_MAP.put('\'',"''");
        STRING_ENCODE_MAP.put('\\',"\\\\");
        STRING_ENCODE_MAP.put('\n',"\\n");
        STRING_ENCODE_MAP.put('\r',"\\r");
        STRING_ENCODE_MAP.put('\t',"\\t");
        STRING_ENCODE_MAP.put('"',"\\\"");
        LATEX_ENCODE_MAP.put('\\',"\\\\");
        LATEX_ENCODE_MAP.put('#',"\\#");
        LATEX_ENCODE_MAP.put('$',"\\$");
        LATEX_ENCODE_MAP.put('%',"\\%");
        LATEX_ENCODE_MAP.put('&',"\\&");
        LATEX_ENCODE_MAP.put('~',"\\~");
        LATEX_ENCODE_MAP.put('_',"\\_");
        LATEX_ENCODE_MAP.put('^',"\\^");
        LATEX_ENCODE_MAP.put('{',"\\{");
        LATEX_ENCODE_MAP.put('}',"\\}");
        LATEX_ENCODE_MAP.put('\u00A1',"!'");
        LATEX_ENCODE_MAP.put('\u00BF',"?'");
        LATEX_ENCODE_MAP.put('\u00C0',"\\`{A}");
        LATEX_ENCODE_MAP.put('\u00C1',"\\'{A}");
        LATEX_ENCODE_MAP.put('\u00C2',"\\^{A}");
        LATEX_ENCODE_MAP.put('\u00C3',"\\H{A}");
        LATEX_ENCODE_MAP.put('\u00C4',"\\\"{A}");
        LATEX_ENCODE_MAP.put('\u00C5',"\\AA");
        LATEX_ENCODE_MAP.put('\u00C6',"\\AE");
        LATEX_ENCODE_MAP.put('\u00C7',"\\c{C}");
        LATEX_ENCODE_MAP.put('\u00C8',"\\`{E}");
        LATEX_ENCODE_MAP.put('\u00C9',"\\'{E}");
        LATEX_ENCODE_MAP.put('\u00CA',"\\^{E}");
        LATEX_ENCODE_MAP.put('\u00CB',"\\\"{E}");
        LATEX_ENCODE_MAP.put('\u00CC',"\\`{I}");
        LATEX_ENCODE_MAP.put('\u00CD',"\\'{I}");
        LATEX_ENCODE_MAP.put('\u00CE',"\\^{I}");
        LATEX_ENCODE_MAP.put('\u00CF',"\\\"{I}");
// todo \u00D0
        LATEX_ENCODE_MAP.put('\u00D1',"\\H{N}");
        LATEX_ENCODE_MAP.put('\u00D2',"\\`{O}");
        LATEX_ENCODE_MAP.put('\u00D3',"\\'{O}");
        LATEX_ENCODE_MAP.put('\u00D4',"\\^{O}");
        LATEX_ENCODE_MAP.put('\u00D5',"\\H{O}");
        LATEX_ENCODE_MAP.put('\u00D6',"\\\"{O}");
// todo \u00D7
        LATEX_ENCODE_MAP.put('\u00D8',"\\O");
        LATEX_ENCODE_MAP.put('\u00D9',"\\`{U}");
        LATEX_ENCODE_MAP.put('\u00DA',"\\'{U}");
        LATEX_ENCODE_MAP.put('\u00DB',"\\^{U}");
        LATEX_ENCODE_MAP.put('\u00DC',"\\\"{U}");
        LATEX_ENCODE_MAP.put('\u00DD',"\\'{Y}");
// todo \u00DE
        LATEX_ENCODE_MAP.put('\u00DF',"\\ss");
        LATEX_ENCODE_MAP.put('\u00E0',"\\`{a}");
        LATEX_ENCODE_MAP.put('\u00E1',"\\'{a}");
        LATEX_ENCODE_MAP.put('\u00E2',"\\^{a}");
        LATEX_ENCODE_MAP.put('\u00E3',"\\H{a}");
        LATEX_ENCODE_MAP.put('\u00E4',"\\\"{a}");
        LATEX_ENCODE_MAP.put('\u00E5',"\\aa");
        LATEX_ENCODE_MAP.put('\u00E6',"\\ae");
        LATEX_ENCODE_MAP.put('\u00E7',"\\c{c}");
        LATEX_ENCODE_MAP.put('\u00E8',"\\`{e}");
        LATEX_ENCODE_MAP.put('\u00E9',"\\'{e}");
        LATEX_ENCODE_MAP.put('\u00EA',"\\^{e}");
        LATEX_ENCODE_MAP.put('\u00EB',"\\\"{e}");
        LATEX_ENCODE_MAP.put('\u00EC',"\\`{i}");
        LATEX_ENCODE_MAP.put('\u00ED',"\\'{i}");
        LATEX_ENCODE_MAP.put('\u00EE',"\\^{i}");
        LATEX_ENCODE_MAP.put('\u00EF',"\\\"{i}");
// todo \u00F0
        LATEX_ENCODE_MAP.put('\u00F1',"\\H{n}");
        LATEX_ENCODE_MAP.put('\u00F2',"\\`{o}");
        LATEX_ENCODE_MAP.put('\u00F3',"\\'{o}");
        LATEX_ENCODE_MAP.put('\u00F4',"\\^{o}");
        LATEX_ENCODE_MAP.put('\u00F5',"\\H{o}");
        LATEX_ENCODE_MAP.put('\u00F6',"\\\"{o}");
// todo \u00F7
        LATEX_ENCODE_MAP.put('\u00F8',"\\o");
        LATEX_ENCODE_MAP.put('\u00F9',"\\`{u}");
        LATEX_ENCODE_MAP.put('\u00FA',"\\'{u}");
        LATEX_ENCODE_MAP.put('\u00FB',"\\^{u}");
        LATEX_ENCODE_MAP.put('\u00FC',"\\\"{u}");
        LATEX_ENCODE_MAP.put('\u00FD',"\\'{y}");
// todo \u00FE
        LATEX_ENCODE_MAP.put('\u00FF',"\\\"{y}");
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * containing only valid characters for a java class name.
     *
     * @param name The string that has to be transformed into a valid class
     * name.
     * @return The encoded <code>String</code> object.
     * @see #encodeUrl(String)
     * @see #encodeHtml(String)
     * @see #encodeXml(String)
     * @see #encodeSql(String)
     * @see #encodeLatex(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeClassname(String name)
    {
        if (null == name)
        {
            return null;
        }
        Pattern pattern = Pattern.compile("[^\\w]");
        Matcher matcher = pattern.matcher(name);
        return matcher.replaceAll("_");
    }
    private static boolean needsUrlEncoding(String source)
    {
        if (null == source)
        {
            return false;
        }
        // check if the string needs encoding first since
        // the URLEncoder always allocates a StringBuffer, even when the
        // string is returned as-is
        boolean encode = false;
        char ch;
        for (int i = 0; i < source.length(); i++)
        {
            ch = source.charAt(i);
            if (ch >= 'a' && ch <= 'z' ||
                ch >= 'A' && ch <= 'Z' ||
                ch >= '0' && ch <= '9' ||
                ch == '-' || ch == '_' || ch == '.' || ch == '*')
            {
                continue;
            }
            encode = true;
            break;
        }
        return encode;
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * containing only valid URL characters.
     *
     * @param source The string that has to be transformed into a valid URL
     * string.
     * @return The encoded <code>String</code> object.
     * @see #encodeClassname(String)
     * @see #encodeUrlValue(String)
     * @see #encodeHtml(String)
     * @see #encodeXml(String)
     * @see #encodeSql(String)
     * @see #encodeLatex(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeUrl(String source)
    {
        if (!needsUrlEncoding(source))
        {
            return source;
        }
        try
        {
            return URLEncoder.encode(source, ENCODING_ISO_8859_1);
        }
        ///CLOVER:OFF
        catch (UnsupportedEncodingException e)
        {
            // this should never happen, ISO-8859-1 is a standard encoding
            throw new RuntimeException(e);
        }
        ///CLOVER:ON
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * only pure US Ascii strings are preserved and URL encoded in a regular
     * way. Strings with characters from other encodings will be encoded in a
     * RIFE-specific manner to allow international data to passed along the
     * query string.
     *
     * @param source The string that has to be transformed into a valid URL
     * parameter string.
     * @return The encoded <code>String</code> object.
     * @see #decodeUrlValue(String)
     * @see #encodeClassname(String)
     * @see #encodeUrl(String)
     * @see #encodeHtml(String)
     * @see #encodeXml(String)
     * @see #encodeSql(String)
     * @see #encodeLatex(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeUrlValue(String source)
    {
        if (!needsUrlEncoding(source))
        {
            return source;
        }
        // check if the string is valid US-ASCII encoding
        boolean         valid = true;
        CharsetEncoder encoder = CHARSET_US_ASCII.newEncoder();
        try
        {
            encoder.encode(CharBuffer.wrap(source));
        }
        catch (CharacterCodingException e)
        {
            valid = false;
        }
        try
        {
            // if it is valid US-ASCII, use the regular URL encoding method
            if (valid)
            {
                    return URLEncoder.encode(source, ENCODING_US_ASCII);
            }
            // otherwise, base-64 encode the UTF-8 bytes and mark the string
            // as being encoded in a special way
            else
            {
                StringBuilder encoded = new StringBuilder("%02%02");
                String base64 = Base64.encodeToString(source.getBytes(ENCODING_UTF_8), false);
                String base64_urlsafe = replace(base64, "=", "%3D");
                encoded.append(base64_urlsafe);
                return encoded.toString();
            }
        }
        ///CLOVER:OFF
        catch (UnsupportedEncodingException e)
        {
            // this should never happen, ISO-8859-1 is a standard encoding
            throw new RuntimeException(e);
        }
        ///CLOVER:ON
    }
    /**
     * Decodes a <code>String</code> that has been encoded in a RIFE-specific
     * manner for URL usage.. Before calling this method, you should first
     * verify if the value needs decoding by using the
     * <code>doesUrlValueNeedDecoding(String)</code> method.
     *
     * @param source the value that has been encoded for URL usage in a
     * RIFE-specific way
     * @return The decoded <code>String</code> object.
     * @see #encodeUrlValue(String)
     * @see #doesUrlValueNeedDecoding(String)
     * @since 1.0
     */
    public static String decodeUrlValue(String source)
    {
        try
        {
            byte[] decoded = Base64.decode(source.substring(2));
            if (null == decoded)
            {
                return null;
            }
            else
            {
                return new String(decoded, StringUtils.ENCODING_UTF_8);
            }
        }
        ///CLOVER:OFF
        catch (UnsupportedEncodingException e)
        {
            // this should never happen, UTF-8 is a standard encoding
            throw new RuntimeException(e);
        }
        ///CLOVER:ON
    }
    /**
     * Checks if a <code>String</code> is encoded in a RIFE-specific manner
     * for URL usage.
     *
     * @param source the value that might have been encoded for URL usage in a
     * RIFE-specific way
     * @return <code>true</code> if the value is encoded in the RIFE-specific
     * format; and
     * <p><code>false</code> otherwise
     * @see #encodeUrlValue(String)
     * @see #decodeUrlValue(String)
     * @since 1.0
     */
    public static boolean doesUrlValueNeedDecoding(String source)
    {
        if (source != null &&
            source.length() > 2 &&
            source.startsWith("\u0002\u0002"))
        {
            return true;
        }
        return false;
    }
    private static boolean needsHtmlEncoding(String source, boolean defensive)
    {
        if (null == source)
        {
            return false;
        }
        boolean encode = false;
        char ch;
        for (int i = 0; i < source.length(); i++)
        {
            ch = source.charAt(i);
            if ((defensive || (ch != '\u0022' && ch != '\u0026' && ch != '\u003C' && ch != '\u003E')) &&
                ch < '\u00A0')
            {
                continue;
            }
            encode = true;
            break;
        }
        return encode;
    }
    /**
     *
     * @since 1.6
     */
    public static String decodeHtml(String source)
    {
        if (null == source ||
            0 == source.length())
        {
            return source;
        }
        int        current_index = 0;
        int        delimiter_start_index = 0;
        int        delimiter_end_index = 0;
        StringBuilder result = null;
        while (current_index <= source.length())
        {
            delimiter_start_index = source.indexOf('&', current_index);
            if (delimiter_start_index != -1)
            {
                delimiter_end_index = source.indexOf(';', delimiter_start_index + 1);
                if (delimiter_end_index != -1)
                {
                    // ensure that the string builder is setup correctly
                    if (null == result)
                    {
                        result = new StringBuilder();
                    }
                    // add the text that leads up to this match
                    if (delimiter_start_index > current_index)
                    {
                        result.append(source.substring(current_index, delimiter_start_index));
                    }
                    // add the decoded entity
                    String entity = source.substring(delimiter_start_index, delimiter_end_index + 1);
                    current_index = delimiter_end_index + 1;
                    // try to decoded numeric entities
                    if (entity.charAt(1) == '#')
                    {
                        int start = 2;
                        int radix = 10;
                        // check if the number is hexadecimal
                        if (entity.charAt(2) == 'X' || entity.charAt(2) == 'x')
                        {
                            start++;
                            radix = 16;
                        }
                        try
                        {
                            Character c = new Character((char)Integer.parseInt(entity.substring(start, entity.length() - 1), radix));
                            result.append(c);
                        }
                        // when the number of the entity can't be parsed, add the entity as-is
                        catch (NumberFormatException e)
                        {
                            result.append(entity);
                        }
                    }
                    else
                    {
                        // try to decode the entity as a literal
                        Character decoded = HTML_DECODE_MAP.get(entity);
                        if (decoded != null)
                        {
                            result.append(decoded);
                        }
                        // if there was no match, add the entity as-is
                        else
                        {
                            result.append(entity);
                        }
                    }
                }
                else
                {
                    break;
                }
            }
            else
            {
                break;
            }
        }
        if (null == result)
        {
            return source;
        }
        else if (current_index < source.length())
        {
            result.append(source.substring(current_index));
        }
        return result.toString();
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * containing only valid Html characters.
     *
     * @param source The string that has to be transformed into a valid Html
     * string.
     * @return The encoded <code>String</code> object.
     * @see #encodeClassname(String)
     * @see #encodeUrl(String)
     * @see #encodeUrlValue(String)
     * @see #encodeXml(String)
     * @see #encodeSql(String)
     * @see #encodeString(String)
     * @see #encodeLatex(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeHtml(String source)
    {
        if (needsHtmlEncoding(source, false))
        {
            return encode(source, HTML_ENCODER_FALLBACK, AGGRESSIVE_HTML_ENCODE_MAP, DEFENSIVE_HTML_ENCODE_MAP);
        }
        return source;
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * containing as much as possible Html characters. It is safe to already
     * feed existing Html to this method since &amp;, &lt; and &gt; will not
     * be encoded.
     *
     * @param source The string that has to be transformed into a valid Html
     * string.
     * @return The encoded <code>String</code> object.
     * @see #encodeClassname(String)
     * @see #encodeUrl(String)
     * @see #encodeUrlValue(String)
     * @see #encodeXml(String)
     * @see #encodeSql(String)
     * @see #encodeString(String)
     * @see #encodeLatex(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeHtmlDefensive(String source)
    {
        if (needsHtmlEncoding(source, true))
        {
            return encode(source, null, DEFENSIVE_HTML_ENCODE_MAP);
        }
        return source;
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * containing only valid XML characters.
     *
     * @param source The string that has to be transformed into a valid XML
     * string.
     * @return The encoded <code>String</code> object.
     * @see #encodeClassname(String)
     * @see #encodeUrl(String)
     * @see #encodeUrlValue(String)
     * @see #encodeHtml(String)
     * @see #encodeSql(String)
     * @see #encodeString(String)
     * @see #encodeLatex(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeXml(String source)
    {
        return encode(source, null, XML_ENCODE_MAP);
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * containing only valid <code>String</code> characters.
     *
     * @param source The string that has to be transformed into a valid
     * sequence of <code>String</code> characters.
     * @return The encoded <code>String</code> object.
     * @see #encodeClassname(String)
     * @see #encodeUrl(String)
     * @see #encodeUrlValue(String)
     * @see #encodeHtml(String)
     * @see #encodeXml(String)
     * @see #encodeSql(String)
     * @see #encodeLatex(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeString(String source)
    {
        return encode(source, null, STRING_ENCODE_MAP);
    }
    /**
     * Transforms a provided <code>String</code> object into a series of
     * unicode escape codes.
     *
     * @param source The string that has to be transformed into a valid
     * sequence of unicode escape codes
     * @return The encoded <code>String</code> object.
     * @see #encodeClassname(String)
     * @see #encodeUrl(String)
     * @see #encodeUrlValue(String)
     * @see #encodeHtml(String)
     * @see #encodeXml(String)
     * @see #encodeSql(String)
     * @see #encodeLatex(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeUnicode(String source)
    {
        if (null == source)
        {
            return null;
        }
        StringBuilder    encoded = new StringBuilder();
        String            hexstring = null;
        for (int i = 0; i < source.length(); i++)
        {
            hexstring = Integer.toHexString((int)source.charAt(i)).toUpperCase();
            encoded.append("\\u");
            // fill with zeros
            for (int j = hexstring.length(); j < 4; j++)
            {
                encoded.append("0");
            }
            encoded.append(hexstring);
        }
        return encoded.toString();
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * containing only valid Sql characters.
     *
     * @param source The string that has to be transformed into a valid Sql
     * string.
     * @return The encoded <code>String</code> object.
     * @see #encodeClassname(String)
     * @see #encodeUrl(String)
     * @see #encodeUrlValue(String)
     * @see #encodeHtml(String)
     * @see #encodeXml(String)
     * @see #encodeString(String)
     * @see #encodeLatex(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeSql(String source)
    {
        return encode(source, null, SQL_ENCODE_MAP);
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * containing only valid LaTeX characters.
     *
     * @param source The string that has to be transformed into a valid LaTeX
     * string.
     * @return The encoded <code>String</code> object.
     * @see #encodeClassname(String)
     * @see #encodeUrl(String)
     * @see #encodeUrlValue(String)
     * @see #encodeHtml(String)
     * @see #encodeXml(String)
     * @see #encodeSql(String)
     * @see #encodeString(String)
     * @see #encodeRegexp(String)
     * @since 1.0
     */
    public static String encodeLatex(String source)
    {
        if (null == source)
        {
            return null;
        }
        source = encode(source, null, LATEX_ENCODE_MAP);
        source = StringUtils.replace(source, "latex", "\\LaTeX", false);
        return source;
    }
    /**
     * Transforms a provided <code>String</code> object into a new string,
     * using the mapping that are provided through the supplied encoding
     * table.
     *
     * @param source The string that has to be transformed into a valid
     * string, using the mappings that are provided through the supplied
     * encoding table.
     * @param encodingTables A <code>Map</code> object containing the mappings
     * to transform characters into valid entities. The keys of this map
     * should be <code>Character</code> objects and the values
     * <code>String</code> objects.
     * @return The encoded <code>String</code> object.
     * @since 1.0
     */
    private static String encode(String source, EncoderFallbackHandler fallbackHandler, Map<Character, String>... encodingTables)
    {
        if (null == source)
        {
            return null;
        }
        if (null == encodingTables ||
            0 == encodingTables.length)
        {
            return source;
        }
        StringBuilder    encoded_string = null;
        char[]            string_to_encode_array = source.toCharArray();
        int                last_match = -1;
        for (int i = 0; i < string_to_encode_array.length; i++)
        {
            char char_to_encode = string_to_encode_array[i];
            for (Map<Character, String> encoding_table : encodingTables)
            {
                if (encoding_table.containsKey(char_to_encode))
                {
                    encoded_string = prepareEncodedString(source, encoded_string, i, last_match, string_to_encode_array);
                    encoded_string.append(encoding_table.get(char_to_encode));
                    last_match = i;
                }
            }
            if (fallbackHandler != null &&
                last_match < i &&
                fallbackHandler.hasFallback(char_to_encode))
            {
                encoded_string = prepareEncodedString(source, encoded_string, i, last_match, string_to_encode_array);
                fallbackHandler.appendFallback(encoded_string, char_to_encode);
                last_match = i;
            }
        }
        if (null == encoded_string)
        {
            return source;
        }
        else
        {
            int difference = string_to_encode_array.length-(last_match+1);
            if (difference > 0)
            {
                encoded_string.append(string_to_encode_array, last_match+1, difference);
            }
            return encoded_string.toString();
        }
    }
    private static StringBuilder prepareEncodedString(String source, StringBuilder encodedString, int i, int lastMatch, char[] stringToEncodeArray)
    {
        if (null == encodedString)
        {
            encodedString = new StringBuilder(source.length());
        }
        int difference = i - (lastMatch + 1);
        if (difference > 0)
        {
            encodedString.append(stringToEncodeArray, lastMatch + 1, difference);
        }
        return encodedString;
    }
    private static interface EncoderFallbackHandler
    {
        abstract boolean hasFallback(char character);
        abstract void appendFallback(StringBuilder encodedBuffer, char character);
    }
    private static class HtmlEncoderFallbackHandler implements EncoderFallbackHandler
    {
        private final static String PREFIX = "&#";
        private final static String SUFFIX = ";";
        public boolean hasFallback(char character)
        {
            if (character < '\u00A0')
            {
                return false;
            }
            return true;
        }
        public void appendFallback(StringBuilder encodedBuffer, char character)
        {
            encodedBuffer.append(PREFIX);
            encodedBuffer.append((int)character);
            encodedBuffer.append(SUFFIX);
        }
    }
    /**
     * Transforms a provided <code>String</code> object into a literal that can
     * be included into a regular expression {@link Pattern} as-is. None of the
     * regular expression escapes in the string will be functional anymore.
     *
     * @param source The string that has to be escaped as a literal
     * @return The encoded <code>String</code> object.
     * @see #encodeClassname(String)
     * @see #encodeUrl(String)
     * @see #encodeUrlValue(String)
     * @see #encodeHtml(String)
     * @see #encodeXml(String)
     * @see #encodeSql(String)
     * @see #encodeString(String)
     * @see #encodeLatex(String)
     * @since 1.3
     */
    public static String encodeRegexp(String source)
    {
        int regexp_quote_start = source.indexOf("\\E");
        if (-1 == regexp_quote_start)
        {
            return "\\Q" + source + "\\E";
        }
        StringBuilder buffer = new StringBuilder(source.length() * 2);
        buffer.append("\\Q");
        regexp_quote_start = 0;
        int current = 0;
        while (-1 == (regexp_quote_start = source.indexOf("\\E", current)))
        {
            buffer.append(source.substring(current, regexp_quote_start));
            current = regexp_quote_start + 2;
            buffer.append("\\E\\\\E\\Q");
        }
        buffer.append(source.substring(current, source.length()));
        buffer.append("\\E");
        return buffer.toString();
    }
    /**
     * Counts the number of times a substring occures in a provided string in
     * a case-sensitive manner.
     *
     * @param source The <code>String</code> object that will be searched in.
     * @param substring The string whose occurances will we counted.
     * @return An <code>int</code> value containing the number of occurances
     * of the substring.
     * @since 1.0
     */
    public static int count(String source, String substring)
    {
        return count(source, substring, true);
    }
    /**
     * Counts the number of times a substring occures in a provided string.
     *
     * @param source The <code>String</code> object that will be searched in.
     * @param substring The string whose occurances will we counted.
     * @param matchCase A <code>boolean</code> indicating if the match is
     * going to be performed in a case-sensitive manner or not.
     * @return An <code>int</code> value containing the number of occurances
     * of the substring.
     * @since 1.0
     */
    public static int count(String source, String substring, boolean matchCase)
    {
        if (null == source)
        {
            return 0;
        }
        if (null == substring)
        {
            return 0;
        }
        int current_index = 0;
        int substring_index = 0;
        int count = 0;
        if (!matchCase)
        {
            source = source.toLowerCase();
            substring = substring.toLowerCase();
        }
        while (current_index < source.length()-1)
        {
            substring_index = source.indexOf(substring, current_index);
            if (-1 == substring_index)
            {
                break;
            }
            else
            {
                current_index = substring_index + substring.length();
                count++;
            }
        }
        return count;
    }
    /**
     * Splits a string into different parts, using a seperator string to
     * detect the seperation boundaries in a case-sensitive manner. The
     * seperator will not be included in the list of parts.
     *
     * @param source The string that will be split into parts.
     * @param seperator The seperator string that will be used to determine
     * the parts.
     * @return An <code>ArrayList</code> containing the parts as
     * <code>String</code> objects.
     * @since 1.0
     */
    public static ArrayList<String> split(String source, String seperator)
    {
        return split(source, seperator, true);
    }
    /**
     * Splits a string into different parts, using a seperator string to
     * detect the seperation boundaries. The seperator will not be included in
     * the list of parts.
     *
     * @param source The string that will be split into parts.
     * @param seperator The seperator string that will be used to determine
     * the parts.
     * @param matchCase A <code>boolean</code> indicating if the match is
     * going to be performed in a case-sensitive manner or not.
     * @return An <code>ArrayList</code> containing the parts as
     * <code>String</code> objects.
     * @since 1.0
     */
    public static ArrayList<String> split(String source, String seperator, boolean matchCase)
    {
        ArrayList<String>   substrings = new ArrayList<String>();
        if (null == source)
        {
            return substrings;
        }
        if (null == seperator)
        {
            substrings.add(source);
            return substrings;
        }
        int        current_index = 0;
        int        delimiter_index = 0;
        String    element = null;
        String  source_lookup_reference = null;
        if (!matchCase)
        {
            source_lookup_reference = source.toLowerCase();
            seperator = seperator.toLowerCase();
        }
        else
        {
            source_lookup_reference = source;
        }
        while (current_index <= source_lookup_reference.length())
        {
            delimiter_index = source_lookup_reference.indexOf(seperator, current_index);
            if (-1 == delimiter_index)
            {
                element = new String(source.substring(current_index, source.length()));
                substrings.add(element);
                current_index = source.length() + 1;
            }
            else
            {
                element = new String(source.substring(current_index, delimiter_index));
                substrings.add(element);
                current_index = delimiter_index + seperator.length();
            }
        }
        return substrings;
    }
    /**
     * Splits a string into different parts, using a seperator string to
     * detect the seperation boundaries in a case-sensitive manner. The
     * seperator will not be included in the parts array.
     *
     * @param source The string that will be split into parts.
     * @param seperator The seperator string that will be used to determine
     * the parts.
     * @return A <code>String[]</code> array containing the seperated parts.
     * @since 1.0
     */
    public static String[] splitToArray(String source, String seperator)
    {
        return splitToArray(source, seperator, true);
    }
    /**
     * Splits a string into different parts, using a seperator string to
     * detect the seperation boundaries. The seperator will not be included in
     * the parts array.
     *
     * @param source The string that will be split into parts.
     * @param seperator The seperator string that will be used to determine
     * the parts.
     * @param matchCase A <code>boolean</code> indicating if the match is
     * going to be performed in a case-sensitive manner or not.
     * @return A <code>String[]</code> array containing the seperated parts.
     * @since 1.0
     */
    public static String[] splitToArray(String source, String seperator, boolean matchCase)
    {
        ArrayList<String>   substrings = split(source, seperator, matchCase);
        String[]            substrings_array = new String[substrings.size()];
        substrings_array = substrings.toArray(substrings_array);
        return substrings_array;
    }
    /**
     * Splits a string into integers, using a seperator string to detect the
     * seperation boundaries in a case-sensitive manner. If a part couldn't be
     * converted to an integer, it will be omitted from the resulting array.
     *
     * @param source The string that will be split into integers.
     * @param seperator The seperator string that will be used to determine
     * the parts.
     * @return An <code>int[]</code> array containing the seperated parts.
     * @since 1.0
     */
    public static int[] splitToIntArray(String source, String seperator)
    {
        return splitToIntArray(source, seperator, true);
    }
    /**
     * Splits a string into integers, using a seperator string to detect the
     * seperation boundaries. If a part couldn't be converted to an integer,
     * it will be omitted from the resulting array.
     *
     * @param source The string that will be split into integers.
     * @param seperator The seperator string that will be used to determine
     * the parts.
     * @param matchCase A <code>boolean</code> indicating if the match is
     * going to be performed in a case-sensitive manner or not.
     * @return An <code>int[]</code> array containing the seperated parts.
     * @since 1.0
     */
    public static int[] splitToIntArray(String source, String seperator, boolean matchCase)
    {
        ArrayList<String>   string_parts = split(source, seperator, matchCase);
        int                 number_of_valid_parts = 0;
        for (String string_part : string_parts)
        {
            try
            {
                Integer.parseInt(string_part);
                number_of_valid_parts++;
            }
            catch (NumberFormatException e)
            {
                // just continue
            }
        }
        int[]   string_parts_int = (int[]) Array.newInstance(int.class, number_of_valid_parts);
        int     added_parts = 0;
        for (String string_part : string_parts)
        {
            try
            {
                string_parts_int[added_parts] = Integer.parseInt(string_part);
                added_parts++;
            }
            catch (NumberFormatException e)
            {
                // just continue
            }
        }
        return string_parts_int;
    }
    /**
     * Splits a string into bytes, using a seperator string to detect the
     * seperation boundaries in a case-sensitive manner. If a part couldn't be
     * converted to a <code>byte</code>, it will be omitted from the resulting
     * array.
     *
     * @param source The string that will be split into bytes.
     * @param seperator The seperator string that will be used to determine
     * the parts.
     * @return A <code>byte[]</code> array containing the bytes.
     * @since 1.0
     */
    public static byte[] splitToByteArray(String source, String seperator)
    {
        return splitToByteArray(source, seperator, true);
    }
    /**
     * Splits a string into bytes, using a seperator string to detect the
     * seperation boundaries. If a part couldn't be converted to a
     * <code>byte</code>, it will be omitted from the resulting array.
     *
     * @param source The string that will be split into bytes.
     * @param seperator The seperator string that will be used to determine
     * the parts.
     * @param matchCase A <code>boolean</code> indicating if the match is
     * going to be performed in a case-sensitive manner or not.
     * @return A <code>byte[]</code> array containing the bytes.
     * @since 1.0
     */
    public static byte[] splitToByteArray(String source, String seperator, boolean matchCase)
    {
        ArrayList<String>   string_parts = split(source, seperator, matchCase);
        int                 number_of_valid_parts = 0;
        for (String string_part : string_parts)
        {
            try
            {
                Byte.parseByte(string_part);
                number_of_valid_parts++;
            }
            catch (NumberFormatException e)
            {
                // just continue
            }
        }
        byte[]  string_parts_byte = (byte[])Array.newInstance(byte.class, number_of_valid_parts);
        int     added_parts = 0;
        for (String string_part : string_parts)
        {
            try
            {
                string_parts_byte[added_parts] = Byte.parseByte(string_part);
                added_parts++;
            }
            catch (NumberFormatException e)
            {
                // just continue
            }
        }
        return string_parts_byte;
    }
    /**
     * Removes all occurances of a string from the front of another string in
     * a case-sensitive manner.
     *
     * @param source The string in which the matching will be done.
     * @param stringToStrip The string that will be stripped from the front.
     * @return A new <code>String</code> containing the stripped result.
     * @since 1.0
     */
    public static String stripFromFront(String source, String stringToStrip)
    {
        return stripFromFront(source, stringToStrip, true);
    }
    /**
     * Removes all occurances of a string from the front of another string.
     *
     * @param source The string in which the matching will be done.
     * @param stringToStrip The string that will be stripped from the front.
     * @param matchCase A <code>boolean</code> indicating if the match is
     * going to be performed in a case-sensitive manner or not.
     * @return A new <code>String</code> containing the stripping result.
     * @since 1.0
     */
    public static String stripFromFront(String source, String stringToStrip, boolean matchCase)
    {
        if (null == source)
        {
            return null;
        }
        if (null == stringToStrip)
        {
            return source;
        }
        int strip_length = stringToStrip.length();
        int new_index = 0;
        int last_index = 0;
        String  source_lookup_reference = null;
        if (!matchCase)
        {
            source_lookup_reference = source.toLowerCase();
            stringToStrip = stringToStrip.toLowerCase();
        }
        else
        {
            source_lookup_reference = source;
        }
        new_index = source_lookup_reference.indexOf(stringToStrip);
        if (0 == new_index)
        {
            do
            {
                last_index = new_index;
                new_index = source_lookup_reference.indexOf(stringToStrip, new_index+strip_length);
            }
            while (new_index != -1 &&
                   new_index == last_index+strip_length);
            return source.substring(last_index+strip_length);
        }
        else
        {
            return source;
        }
    }
    /**
     * Removes all occurances of a string from the end of another string in a
     * case-sensitive manner.
     *
     * @param source The string in which the matching will be done.
     * @param stringToStrip The string that will be stripped from the end.
     * @return A new <code>String</code> containing the stripped result.
     * @since 1.0
     */
    public static String stripFromEnd(String source, String stringToStrip)
    {
        return stripFromEnd(source, stringToStrip, true);
    }
    /**
     * Removes all occurances of a string from the end of another string.
     *
     * @param source The string in which the matching will be done.
     * @param stringToStrip The string that will be stripped from the end.
     * @param matchCase A <code>boolean</code> indicating if the match is
     * going to be performed in a case-sensitive manner or not.
     * @return A new <code>String</code> containing the stripped result.
     * @since 1.0
     */
    public static String stripFromEnd(String source, String stringToStrip, boolean matchCase)
    {
        if (null == source)
        {
            return null;
        }
        if (null == stringToStrip)
        {
            return source;
        }
        int strip_length = stringToStrip.length();
        int new_index = 0;
        int last_index = 0;
        String  source_lookup_reference = null;
        if (!matchCase)
        {
            source_lookup_reference = source.toLowerCase();
            stringToStrip = stringToStrip.toLowerCase();
        }
        else
        {
            source_lookup_reference = source;
        }
        new_index = source_lookup_reference.lastIndexOf(stringToStrip);
        if (new_index != -1 &&
            source.length() == new_index+strip_length)
        {
            do
            {
                last_index = new_index;
                new_index = source_lookup_reference.lastIndexOf(stringToStrip, last_index-1);
            }
            while (new_index != -1 &&
                   new_index == last_index-strip_length);
            return source.substring(0, last_index);
        }
        else
        {
            return source;
        }
    }
    /**
     * Searches for a string within a specified string in a case-sensitive
     * manner and replaces every match with another string.
     *
     * @param source The string in which the matching parts will be replaced.
     * @param stringToReplace The string that will be searched for.
     * @param replacementString The string that will replace each matching
     * part.
     * @return A new <code>String</code> object containing the replacement
     * result.
     * @since 1.0
     */
    public static String replace(String source, String stringToReplace, String replacementString)
    {
        return replace(source, stringToReplace, replacementString, true);
    }
    /**
     * Searches for a string within a specified string and replaces every
     * match with another string.
     *
     * @param source The string in which the matching parts will be replaced.
     * @param stringToReplace The string that will be searched for.
     * @param replacementString The string that will replace each matching
     * part.
     * @param matchCase A <code>boolean</code> indicating if the match is
     * going to be performed in a case-sensitive manner or not.
     * @return A new <code>String</code> object containing the replacement
     * result.
     * @since 1.0
     */
    public static String replace(String source, String stringToReplace, String replacementString, boolean matchCase)
    {
        if (null == source)
        {
            return null;
        }
        if (null == stringToReplace)
        {
            return source;
        }
        if (null == replacementString)
        {
            return source;
        }
        Iterator<String> string_parts = split(source, stringToReplace, matchCase).iterator();
        StringBuilder        new_string = new StringBuilder();
        while (string_parts.hasNext())
        {
            String string_part = string_parts.next();
            new_string.append(string_part);
            if (string_parts.hasNext())
            {
                new_string.append(replacementString);
            }
        }
        return new_string.toString();
    }
    /**
     * Creates a new string that contains the provided string a number of
     * times.
     *
     * @param source The string that will be repeated.
     * @param count The number of times that the string will be repeated.
     * @return A new <code>String</code> object containing the repeated
     * concatenation result.
     * @since 1.0
     */
    public static String repeat(String source, int count)
    {
        if (null == source)
        {
            return null;
        }
        StringBuilder new_string = new StringBuilder();
        while (count > 0)
        {
            new_string.append(source);
            count --;
        }
        return new_string.toString();
    }
    /**
     * Creates a new array of <code>String</code> objects, containing the
     * elements of a supplied <code>Iterator</code>.
     *
     * @param iterator The iterator containing the elements to create the
     * array with.
     * @return The new <code>String</code> array.
     * @since 1.0
     */
    public static String[] toStringArray(Iterator<String> iterator)
    {
        if (null == iterator)
        {
            return new String[0];
        }
        ArrayList<String>   strings = new ArrayList<String>();
        while (iterator.hasNext())
        {
            strings.add(iterator.next());
        }
        String[] string_array = new String[strings.size()];
        strings.toArray(string_array);
        return string_array;
    }
    /**
     * Creates a new <code>ArrayList</code>, containing the elements of a
     * supplied array of <code>String</code> objects.
     *
     * @param stringArray The array of <code>String</code> objects that have
     * to be converted.
     * @return The new <code>ArrayList</code> with the elements of the
     * <code>String</code> array.
     * @since 1.0
     */
    public static ArrayList<String> toArrayList(String[] stringArray)
    {
        ArrayList<String> strings = new ArrayList<String>();
        if (null == stringArray)
        {
            return strings;
        }
        for (String element : stringArray)
        {
            strings.add(element);
        }
        return strings;
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied <code>Collection</code> of <code>String</code> objects joined
     * by a given seperator.
     *
     * @param collection The <code>Collection</code> containing the elements
     * to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(Collection collection, String seperator)
    {
        if (null == collection)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (0 == collection.size())
        {
            return "";
        }
        else
        {
            StringBuilder result = new StringBuilder();
            for (Object element : collection)
            {
                result.append(String.valueOf(element));
                result.append(seperator);
            }
            result.setLength(result.length()-seperator.length());
            return result.toString();
        }
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The object array containing the elements to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(Object[] array, String seperator)
    {
        return join(array, seperator, null, false);
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The object array containing the elements to join.
     * @param seperator The seperator used to join the string elements.
     * @param delimiter The delimiter used to surround the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(Object[] array, String seperator, String delimiter)
    {
        return join(array, seperator, delimiter, false);
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The object array containing the elements to join.
     * @param seperator The seperator used to join the string elements.
     * @param delimiter The delimiter used to surround the string elements.
     * @param encodeStrings Indicates whether the characters of the string
     * representation of the Array values should be encoded.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(Object[] array, String seperator, String delimiter, boolean encodeStrings)
    {
        if (null == array)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (null == delimiter)
        {
            delimiter = "";
        }
        if (0 == array.length)
        {
            return "";
        }
        else
        {
            int                current_index = 0;
            String            array_value = null;
            StringBuilder    result = new StringBuilder();
            while (current_index < array.length - 1)
            {
                if (null == array[current_index])
                {
                    result.append("null");
                }
                else
                {
                    array_value = String.valueOf(array[current_index]);
                    if (encodeStrings)
                    {
                        array_value = encodeString(array_value);
                    }
                    result.append(delimiter);
                    result.append(array_value);
                    result.append(delimiter);
                }
                result.append(seperator);
                current_index++;
            }
            if (null == array[current_index])
            {
                result.append("null");
            }
            else
            {
                array_value = String.valueOf(array[current_index]);
                if (encodeStrings)
                {
                    array_value = encodeString(array_value);
                }
                result.append(delimiter);
                result.append(array_value);
                result.append(delimiter);
            }
            return result.toString();
        }
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The boolean array containing the values to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(boolean[] array, String seperator)
    {
        if (null == array)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (0 == array.length)
        {
            return "";
        }
        else
        {
            int current_index = 0;
            String result = "";
            while (current_index < array.length - 1)
            {
                result = result + array[current_index] + seperator;
                current_index++;
            }
            result = result +  array[current_index];
            return result;
        }
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The byte array containing the values to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(byte[] array, String seperator)
    {
        if (null == array)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (0 == array.length)
        {
            return "";
        }
        else
        {
            int current_index = 0;
            String result = "";
            while (current_index < array.length - 1)
            {
                result = result + array[current_index] + seperator;
                current_index++;
            }
            result = result +  array[current_index];
            return result;
        }
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The double array containing the values to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(double[] array, String seperator)
    {
        if (null == array)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (0 == array.length)
        {
            return "";
        }
        else
        {
            int current_index = 0;
            String result = "";
            while (current_index < array.length - 1)
            {
                result = result + array[current_index] + seperator;
                current_index++;
            }
            result = result +  array[current_index];
            return result;
        }
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The float array containing the values to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(float[] array, String seperator)
    {
        if (null == array)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (0 == array.length)
        {
            return "";
        }
        else
        {
            int current_index = 0;
            String result = "";
            while (current_index < array.length - 1)
            {
                result = result + array[current_index] + seperator;
                current_index++;
            }
            result = result +  array[current_index];
            return result;
        }
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The integer array containing the values to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(int[] array, String seperator)
    {
        if (null == array)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (0 == array.length)
        {
            return "";
        }
        else
        {
            int current_index = 0;
            String result = "";
            while (current_index < array.length - 1)
            {
                result = result + array[current_index] + seperator;
                current_index++;
            }
            result = result +  array[current_index];
            return result;
        }
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The long array containing the values to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(long[] array, String seperator)
    {
        if (null == array)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (0 == array.length)
        {
            return "";
        }
        else
        {
            int current_index = 0;
            String result = "";
            while (current_index < array.length - 1)
            {
                result = result + array[current_index] + seperator;
                current_index++;
            }
            result = result +  array[current_index];
            return result;
        }
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The short array containing the values to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(short[] array, String seperator)
    {
        if (null == array)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (0 == array.length)
        {
            return "";
        }
        else
        {
            int current_index = 0;
            String result = "";
            while (current_index < array.length - 1)
            {
                result = result + array[current_index] + seperator;
                current_index++;
            }
            result = result +  array[current_index];
            return result;
        }
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The char array containing the values to join.
     * @param seperator The seperator used to join the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(char[] array, String seperator)
    {
        return join(array, seperator, null);
    }
    /**
     * Creates a new <code>String</code> object, containing the elements of a
     * supplied array, joined by a given seperator.
     *
     * @param array The char array containing the values to join.
     * @param seperator The seperator used to join the string elements.
     * @param delimiter The delimiter used to surround the string elements.
     * @return A new <code>String</code> with the join result.
     * @since 1.0
     */
    public static String join(char[] array, String seperator, String delimiter)
    {
        if (null == array)
        {
            return null;
        }
        if (null == seperator)
        {
            seperator = "";
        }
        if (null == delimiter)
        {
            delimiter = "";
        }
        if (0 == array.length)
        {
            return "";
        }
        else
        {
            int current_index = 0;
            StringBuilder    result = new StringBuilder();
            while (current_index < array.length - 1)
            {
                result.append(delimiter);
                result.append(array[current_index]);
                result.append(delimiter);
                result.append(seperator);
                current_index++;
            }
            result.append(delimiter);
            result.append(String.valueOf(array[current_index]));
            result.append(delimiter);
            return result.toString();
        }
    }
    /**
     * Returns an array that contains all the occurances of a substring in a
     * string in the correct order. The search will be performed in a
     * case-sensitive manner.
     *
     * @param source The <code>String</code> object that will be searched in.
     * @param substring The string whose occurances will we counted.
     * @return An <code>int[]</code> array containing the indices of the
     * substring.
     * @since 1.0
     */
    public static int[] indicesOf(String source, String substring)
    {
        return indicesOf(source, substring, true);
    }
    /**
     * Returns an array that contains all the occurances of a substring in a
     * string in the correct order.
     *
     * @param source The <code>String</code> object that will be searched in.
     * @param substring The string whose occurances will we counted.
     * @param matchCase A <code>boolean</code> indicating if the match is
     * going to be performed in a case-sensitive manner or not.
     * @return An <code>int[]</code> array containing the indices of the
     * substring.
     * @since 1.0
     */
    public static int[] indicesOf(String source, String substring, boolean matchCase)
    {
        if (null == source ||
            null == substring)
        {
            return new int[0];
        }
        String  source_lookup_reference = null;
        if (!matchCase)
        {
            source_lookup_reference = source.toLowerCase();
            substring = substring.toLowerCase();
        }
        else
        {
            source_lookup_reference = source;
        }
        int current_index = 0;
        int substring_index = 0;
        int count = count(source_lookup_reference, substring);
        int[] indices = new int[count];
        int counter = 0;
        while (current_index < source.length()-1)
        {
            substring_index = source_lookup_reference.indexOf(substring, current_index);
            if (-1 == substring_index)
            {
                break;
            }
            else
            {
                current_index = substring_index + substring.length();
                indices[counter] = substring_index;
                counter++;
            }
        }
        return indices;
    }
    /**
     * Matches a collection of regular expressions against a string.
     *
     * @param value The <code>String</code> that will be checked.
     * @param regexps The collection of regular expressions against which the
     * match will be performed.
     * @return The <code>Matcher</code> instance that corresponds to the
     * <code>String</code> that returned a successful match; or
     * <p><code>null</code> if no match could be found.
     * @since 1.0
     */
    public static Matcher getMatchingRegexp(String value, Collection<Pattern> regexps)
    {
        if (value != null &&
            value.length() > 0 &&
            regexps != null &&
            regexps.size() > 0)
        {
            Matcher matcher = null;
            for (Pattern regexp : regexps)
            {
                matcher = regexp.matcher(value);
                if (matcher.matches())
                {
                    return matcher;
                }
            }
        }
        return null;
    }
    /**
     * Matches a collection of strings against a regular expression.
     *
     * @param values The <code>Collection</code> of <code>String</code>
     * objects that will be checked.
     * @param regexp The regular expression <code>Pattern</code> against which
     * the matches will be performed.
     * @return The <code>Matcher</code> instance that corresponds to the
     * <code>String</code> that returned a successful match; or
     * <p><code>null</code> if no match could be found.
     * @since 1.0
     */
    public static Matcher getRegexpMatch(Collection<String> values, Pattern regexp)
    {
        if (values != null &&
            values.size() > 0 &&
            regexp != null)
        {
            Matcher matcher = null;
            for (String value : values)
            {
                matcher = regexp.matcher(value);
                if (matcher.matches())
                {
                    return matcher;
                }
            }
        }
        return null;
    }
    /**
     * Checks if the name filters through an including and an excluding
     * regular expression.
     *
     * @param name The <code>String</code> that will be filtered.
     * @param included The regular expressions that needs to succeed
     * @param excluded The regular expressions that needs to fail
     * @return <code>true</code> if the name filtered through correctly; or
     * <p><code>false</code> otherwise.
     * @since 1.0
     */
    public static boolean filter(String name, Pattern included, Pattern excluded)
    {
        Pattern[] included_array = null;
        if (included != null)
        {
            included_array = new Pattern[] {included};
        }
        Pattern[] excluded_array = null;
        if (excluded != null)
        {
            excluded_array = new Pattern[] {excluded};
        }
        return filter(name, included_array, excluded_array);
    }
    /**
     * Checks if the name filters through a series of including and excluding
     * regular expressions.
     *
     * @param name The <code>String</code> that will be filtered.
     * @param included An array of regular expressions that need to succeed
     * @param excluded An array of regular expressions that need to fail
     * @return <code>true</code> if the name filtered through correctly; or
     * <p><code>false</code> otherwise.
     * @since 1.0
     */
    public static boolean filter(String name, Pattern[] included, Pattern[] excluded)
    {
        if (null == name)
        {
            return false;
        }
        boolean accepted = false;
        // retain only the includes
        if (null == included)
        {
            accepted = true;
        }
        else
        {
            for (Pattern pattern : included)
            {
                if (pattern != null &&
                    pattern.matcher(name).matches())
                {
                    accepted = true;
                    break;
                }
            }
        }
        // remove the excludes
        if (accepted &&
            excluded != null)
        {
            for (Pattern pattern : excluded)
            {
                if (pattern != null &&
                    pattern.matcher(name).matches())
                {
                    accepted = false;
                    break;
                }
            }
        }
        return accepted;
    }
    /**
     * Ensure that the first character of the provided string is upper case.
     *
     * @param source The <code>String</code> to capitalize.
     * @return The capitalized <code>String</code>.
     * @since 1.0
     */
    public static String capitalize(String source)
    {
        if (source == null || source.length() == 0)
        {
            return source;
        }
        if (source.length() > 1 &&
            Character.isUpperCase(source.charAt(0)))
        {
            return source;
        }
        char chars[] = source.toCharArray();
        chars[0] = Character.toUpperCase(chars[0]);
        return new String(chars);
    }
    /**
     * Ensure that the first character of the provided string lower case.
     *
     * @param source The <code>String</code> to uncapitalize.
     * @return The uncapitalized <code>String</code>.
     * @since 1.5
     */
    public static String uncapitalize(String source)
    {
        if (source == null || source.length() == 0)
        {
            return source;
        }
        if (source.length() > 1 &&
            Character.isLowerCase(source.charAt(0)))
        {
            return source;
        }
        char chars[] = source.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }
    private static String convertUrl(String source, Pattern pattern, boolean shorten, boolean sanitize, boolean no_follow)
    {
        int max_length = 1024;
        String result = source;
        Matcher url_matcher = pattern.matcher(source);
        boolean found = url_matcher.find();
        if (found)
        {
            String visual_url = null;
            String actual_url = null;
            int last = 0;
            StringBuilder sb = new StringBuilder();
            do
            {
                actual_url = url_matcher.group(1);
                if (url_matcher.groupCount() > 1)
                {
                    visual_url = url_matcher.group(2);
                }
                else
                {
                    visual_url = actual_url;
                }
                if (sanitize)
                {
                    // defang javascript
                    actual_url = StringUtils.replace(actual_url, "javascript:", "");
                    // fill in http:// for URLs that don't begin with /
                    if ((actual_url.indexOf("://") == -1) &&
                        (!actual_url.startsWith("/")))
                    {
                        actual_url = "http://"+actual_url;
                    }
                }
                if (pattern.equals(BBCODE_BAREURL))
                {
                    sb.append(source.substring(last, url_matcher.start(1)));
                }
                else
                {
                    sb.append(source.substring(last, url_matcher.start(0)));
                }
                sb.append("<a href=\"");
                sb.append(actual_url);
                sb.append("\"");
                if (actual_url.startsWith("http://") ||
                    actual_url.startsWith("https://"))
                {
                    sb.append(" target=\"_blank\"");
                }
                if (no_follow)
                {
                    sb.append(" rel=\"nofollow\"");
                }
                sb.append(">");
                if (visual_url.length() <= max_length || !shorten)
                {
                    sb.append(visual_url);
                }
                else
                {
                    String ellipsis = "...";
                    int query_index = visual_url.indexOf("?");
                    // hack query string off
                    // keep '?'
                    if (query_index != -1)
                    {
                        visual_url = visual_url.substring(0, query_index + 1) + ellipsis;
                    }
                    if (visual_url.length() >= max_length)
                    {
                        int last_slash = visual_url.lastIndexOf("/");
                        int start_slash = visual_url.indexOf("/", visual_url.indexOf("://")+3);
                        if (last_slash != start_slash)
                        {
                            visual_url = visual_url.substring(0, start_slash + 1) + ellipsis + visual_url.substring(last_slash);
                        }
                    }
                    sb.append(visual_url);
                }
                sb.append("</a>");
                if (pattern.equals(BBCODE_BAREURL))
                {
                    last = url_matcher.end(1);
                }
                else
                {
                    last = url_matcher.end(0);
                }
                found = url_matcher.find();
            }
            while (found);
            sb.append(source.substring(last));
            result = sb.toString();
        }
        return result;
    }
    private static String parseBBCode(String source, boolean shorten, boolean sanitize, boolean convert_bare, boolean no_follow)
    {
        String result = source;
        result = StringUtils.replace(result, "[b]", "<b>", false);
        result = StringUtils.replace(result, "[/b]", "</b>", false);
        result = StringUtils.replace(result, "[u]", "<u>", false);
        result = StringUtils.replace(result, "[/u]", "</u>", false);
        result = StringUtils.replace(result, "[i]", "<i>", false);
        result = StringUtils.replace(result, "[/i]", "</i>", false);
        result = StringUtils.replace(result, "[pre]", "<pre>", false);
        result = StringUtils.replace(result, "[/pre]", "</pre>", false);
        String            resultCopy = result;
        String            resultLowerCopy = result.toLowerCase();
        StringBuilder    buffer = new StringBuilder();
        int startIndex;
        int endIndex;
        while (-1 != (startIndex = resultLowerCopy.indexOf("[*]")))
        {
            int begin = resultLowerCopy.indexOf("[list]", startIndex + 3);
            int end = resultLowerCopy.indexOf("[/list]", startIndex + 3);
            int next = resultLowerCopy.indexOf("[*]", startIndex + 3); // 3 == sizeof [*]
            if (begin == -1)
            {
                begin = Integer.MAX_VALUE;
            }
            if (end == -1)
            {
                end = Integer.MAX_VALUE;
            }
            if (next == -1)
            {
                next = Integer.MAX_VALUE;
            }
            if (next < begin && next < end)
            {
                endIndex = next;
            }
            else if (begin < next && begin < end)
            {
                endIndex = begin;
            }
            else if (end < next && end < begin)
            {
                endIndex = end;
            }
            else
            {
                endIndex = resultLowerCopy.length();
            }
            buffer
                .append(resultCopy.substring(0, startIndex))
                .append("<li>")
                .append(resultCopy.substring(startIndex + 3, endIndex)) // 3 == sizeof [*]
                .append("</li>");
            resultCopy = resultCopy.substring(endIndex);
            resultLowerCopy = resultLowerCopy.substring(endIndex);
        }
        buffer.append(resultCopy.substring(0));
        result = buffer.toString();
        result = StringUtils.replace(result, "[list]", "<ul>", false);
        result = StringUtils.replace(result, "[/list]", "</ul>", false);
        Matcher color_matcher = BBCODE_COLOR.matcher(result);
        result = color_matcher.replaceAll("<font color=\"$1\">");
        result = StringUtils.replace(result, "[/color]", "</font>", false);
        Matcher size_matcher = BBCODE_SIZE.matcher(result);
        result = size_matcher.replaceAll("<font size=\"$1\">");
        result = StringUtils.replace(result, "[/size]", "</font>", false);
        result = convertUrl(result, BBCODE_URL_SHORT, shorten, sanitize, no_follow);
        result = convertUrl(result, BBCODE_URL_LONG, shorten, sanitize, no_follow);
        if (convert_bare)
        {
            result = convertUrl(result, BBCODE_BAREURL, shorten, sanitize, no_follow);
        }
        Matcher img_matcher = BBCODE_IMG.matcher(result);
        result = img_matcher.replaceAll("<div class=\"bbcode_img\"><img src=\"$1\" border=\"0\" alt=\"\" /></div>");
        Matcher quote_matcher_long = BBCODE_QUOTE_LONG.matcher(result);
        result = quote_matcher_long.replaceAll("<div class=\"quoteaccount\">$1:</div><div class=\"quotebody\">");
        result = StringUtils.replace(result, "[quote]", "<div class=\"quotebody\">", false);
        result = StringUtils.replace(result, "[/quote]", "</div>", false);
        result = StringUtils.replace(result, "\r\n", "<br />\r");
        result = StringUtils.replace(result, "\n", "<br />\n");
        result = StringUtils.replace(result, "\r", "\r\n");
        // remove the BR that could be added due to code formatting ppl
        // use to format lists
        result = StringUtils.replace(result, "ul><br />\r\n", "ul>\r\n");
        result = StringUtils.replace(result, "ul><br />\n", "ul>\n");
        return result;
    }
    /**
     * Converts a <code>String</code> to a <code>boolean</code> value.
     *
     * @param value The <code>String</code> to convert.
     * @return The corresponding <code>boolean</code> value.
     * @since 1.0
     */
    public static boolean convertToBoolean(String value)
    {
        if (null == value)
        {
            return false;
        }
        if (value.equals("1") ||
            value.equalsIgnoreCase("t") ||
            value.equalsIgnoreCase("true") ||
            value.equalsIgnoreCase("y") ||
            value.equalsIgnoreCase("yes") ||
            value.equalsIgnoreCase("on"))
        {
            return true;
        }
        return false;
    }
    /**
     * Converts all tabs on a line to spaces according to the provided tab
     * width.
     *
     * @param line The line whose tabs have to be converted.
     * @param tabWidth The tab width.
     * @return A new <code>String</code> object containing the line with the
     * replaced tabs.
     * @since 1.0
     */
    public static String convertTabsToSpaces(String line, int tabWidth)
    {
        StringBuilder result = new StringBuilder();
        int tab_index = -1;
        int last_tab_index = 0;
        int added_chars = 0;
        int tab_size;
        while ((tab_index = line.indexOf("\t", last_tab_index)) != -1)
        {
            tab_size = tabWidth-((tab_index+added_chars)%tabWidth);
            if (0 == tab_size)
            {
                tab_size = tabWidth;
            }
            added_chars += tab_size-1;
            result.append(line.substring(last_tab_index, tab_index));
            result.append(StringUtils.repeat(" ", tab_size));
            last_tab_index = tab_index+1;
        }
        if (0 == last_tab_index)
        {
            return line;
        }
        else
        {
            result.append(line.substring(last_tab_index));
        }
        return result.toString();
    }
    /**
     * Ensures that all whitespace is removed from a <code>String</code>.
     * <p>It also works with a <code>null</code> argument.
     *
     * @param source The <code>String</code> to trim.
     * @return The trimmed <code>String</code>.
     * @since 1.0
     */
    public static String trim(String source)
    {
        if (source == null || source.length() == 0)
        {
            return source;
        }
        return source.trim();
    }
    /**
     * Reformats a string where lines that are longer than <tt>width</tt>
     * are split apart at the earliest wordbreak or at maxLength, whichever is
     * sooner. If the width specified is less than 5 or greater than the input
     * Strings length the string will be returned as is.
     * <p>
     * Please note that this method can be lossy - trailing spaces on wrapped
     * lines may be trimmed.
     *
     * @param input the String to reformat.
     * @param width the maximum length of any one line.
     * @return a new String with reformatted as needed.
     */
    public static String wordWrap(String input, int width, Locale locale)
    {
        // handle invalid input
        if (input == null)
        {
            return "";
        }
        else if (width < 5)
        {
            return input;
        }
        else if (width >= input.length())
        {
            return input;
        }
        // default locale
        if (locale == null)
        {
            locale = Locale.US;
        }
        StringBuilder buffer = new StringBuilder(input.length());
        int        current_index = 0;
        int        delimiter_index = 0;
        String    seperator = "\n";
        String    line;
        // go over the input string and jump from line to line
        while (current_index <= input.length())
        {
            // look for the next linebreak
            delimiter_index = input.indexOf(seperator, current_index);
            // get the line that corresponds to it
            if (-1 == delimiter_index)
            {
                line = new String(input.substring(current_index, input.length()));
                current_index = input.length() + 1;
            }
            else
            {
                line = new String(input.substring(current_index, delimiter_index));
                current_index = delimiter_index + seperator.length();
            }
            // handle the wrapping of the line
            BreakIterator breaks = BreakIterator.getLineInstance(locale);
            breaks.setText(line);
            int line_start = 0;
            int start = breaks.first();
            int end = breaks.next();
            while (end != BreakIterator.DONE)
            {
                // check if the width has been exceeded
                if (end - 1 - line_start >= width)
                {
                    boolean break_line = true;
                    // first check if the last characters were spaces,
                    // if they were and by removing them the width is not
                    // exceeded, just continue
                    if (Character.isWhitespace(line.charAt(end - 1)))
                    {
                        for (int j = end - 1; j >= 0; j--)
                        {
                            if (!Character.isWhitespace(line.charAt(j)))
                            {
                                if (j - line_start < width)
                                {
                                    break_line = false;
                                }
                                break;
                            }
                        }
                    }
                    if (break_line)
                    {
                        String line_breaked = line.substring(line_start, start);
                        // this can happen with trailing whitespace
                        if (line_breaked.length() > width)
                        {
                            line_breaked = line_breaked.substring(0, width);
                        }
                        buffer.append(line_breaked);
                        buffer.append("\n");
                        line_start = start;
                    }
                }
                start = end;
                end = breaks.next();
            }
            if (line_start < line.length())
            {
                buffer.append(line.substring(line_start));
            }
            if (delimiter_index != -1)
            {
                buffer.append("\n");
            }
        }
        return buffer.toString();
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TPCLIDConverter.java
New file
@@ -0,0 +1,758 @@
package com.ximple.eofms.util;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
public abstract class TPCLIDConverter
{
    private final static int SX1200 = 800;
    private final static int SY1200 = 500;
    public static String CoordinateToTpclId(Coordinate dp)
    {
        long orgX, orgY;
        int mapX, mapY;
        int shiftX, shiftY;
        int dx1, dy1;
        int dx2, dy2;
        if (dp == null)
        {
            return null;
        }
        double X = dp.x;
        double Y = dp.y;
        String CoordToTPCLID = "";
        char mapID = CoordinateToSingleMapID(dp);
        if (mapID == 'w')
        {
            return "";
        }
        /* get the origin point of mapID */
        Coordinate Point = getOriginPoint("" + mapID, Integer.MAX_VALUE);
        if (Point == null)
        {
            return null;
        }
        orgX = (long) Point.x;
        orgY = (long) Point.y;
        mapX = intDivision((X - orgX), SX1200);
        if (mapID == 'Z' && mapX >= 100)
        {
            mapX = mapX - 100;
        }
        mapY = intDivision((Y - orgY), SY1200);
        shiftX = (int) (X - orgX) % SX1200;
        shiftY = (int) (Y - orgY) % SY1200;
        dx1 = intDivision((shiftX % 100), 10);
        dy1 = intDivision((shiftY % 100), 10);
        dx2 = (shiftX % 100) % 10;
        dy2 = (shiftY % 100) % 10;
        CoordToTPCLID = "" + mapID;
        CoordToTPCLID = CoordToTPCLID + dataFormat(mapX);
        CoordToTPCLID = CoordToTPCLID + dataFormat(mapY);
        CoordToTPCLID = CoordToTPCLID + intToAscii(shiftX / 100 + asciiToInt("A"));
        CoordToTPCLID = CoordToTPCLID + intToAscii(shiftY / 100 + asciiToInt("A"));
        CoordToTPCLID = CoordToTPCLID + dx1 + dy1 + dx2 + dy2;
        return CoordToTPCLID;
    }
    public static char CoordinateToSingleMapID(Coordinate dp)
    {
        char mapID = 'w';
        String[] strY = StringUtils.splitToArray(Double.toString(dp.y), ".");
        String[] strX = StringUtils.splitToArray(Double.toString(dp.x), ".");
        int intY = Integer.parseInt(strY[0]);
        int intX = Integer.parseInt(strX[0]);
        if (intY > 2944000)
        {
            return mapID;
        }
        if (intY >= 2894000 && intY <= 2944000 && intX >= 10000 && intX <= 90000)
        {
            mapID = 'S';
            return mapID;
        }
        if (intY >= 2614000 && intY <= 2664000 && intX >= 10000 && intX <= 66000)
        {
            mapID = 'X';
            return mapID;
        }
        if (intY >= 2564000 && intY <= 2614000 && intX >= 10000 && intX <= 66000)
        {
            mapID = 'Y';
            return mapID;
        }
        if (intY >= 2675800 && intY <= 2725800 && intX >= 10000 && intX <= 170000)
        {
            mapID = 'Z';
            return mapID;
        }
        if (intY > 2800000)
        {
            return mapID;
        }
        if (intY >= 2750000)
        {
            if (intX < 170000)
            {
                return mapID;
            }
            if (intX < 250000)
            {
                mapID = 'A';
                return mapID;
            }
            if (intX < 330000)
            {
                mapID = 'B';
                return mapID;
            }
            if (intX < 410000)
            {
                mapID = 'C';
                return mapID;
            }
            return mapID;
        }
        if (intY >= 2700000)
        {
            if (intX < 170000)
            {
                return mapID;
            }
            if (intX < 250000)
            {
                mapID = 'D';
                return mapID;
            }
            if (intX < 330000)
            {
                mapID = 'E';
                return mapID;
            }
            if (intX < 410000)
            {
                mapID = 'F';
                return mapID;
            }
            return mapID;
        }
        if (intY >= 2650000)
        {
            if (intX < 170000)
            {
                return mapID;
            }
            if (intX < 250000)
            {
                mapID = 'G';
                return mapID;
            }
            if (intX < 330000)
            {
                mapID = 'H';
                return mapID;
            }
            if (intX < 410000)
            {
                mapID = 'I';
                return mapID;
            }
            return mapID;
        }
        if (intY >= 2600000)
        {
            if (intX < 90000)
            {
                return mapID;
            }
            if (intX < 170000)
            {
                mapID = 'J';
                return mapID;
            }
            if (intX < 250000)
            {
                mapID = 'K';
                return mapID;
            }
            if (intX < 330000)
            {
                mapID = 'L';
                return mapID;
            }
            return mapID;
        }
        if (intY >= 2550000)
        {
            if (intX < 90000)
            {
                return mapID;
            }
            if (intX < 170000)
            {
                mapID = 'M';
                return mapID;
            }
            if (intX < 250000)
            {
                mapID = 'N';
                return mapID;
            }
            if (intX < 330000)
            {
                mapID = 'O';
                return mapID;
            }
            return mapID;
        }
        if (intY >= 2500000)
        {
            if (intX < 90000)
            {
                return mapID;
            }
            if (intX < 170000)
            {
                mapID = 'P';
                return mapID;
            }
            if (intX < 250000)
            {
                mapID = 'Q';
                return mapID;
            }
            if (intX < 330000)
            {
                mapID = 'R';
                return mapID;
            }
            return mapID;
        }
        if (intY >= 2450000)
        {
            if (intX < 90000)
            {
                return mapID;
            }
            if (intX < 170000)
            {
                mapID = 'S';
                return mapID;
            }
            if (intX < 250000)
            {
                mapID = 'T';
                return mapID;
            }
            if (intX < 330000)
            {
                mapID = 'U';
                return mapID;
            }
            return mapID;
        }
        if (intY >= 2400000)
        {
            if (intX < 170000)
            {
                return mapID;
            }
            if (intX < 250000)
            {
                mapID = 'V';
                return mapID;
            }
            if (intX < 330000)
            {
                mapID = 'W';
                return mapID;
            }
            return mapID;
        }
        return mapID;
    }
    public static Envelope convertTpclIdToEnvelope(String tpclid)
    {
        String tempString = "";
        Coordinate point = null;
        Coordinate tempPoint = null;
        double width, height;
        if (tpclid.length() < 5)
        {
            return null;
        }
        tempString = tpclid.substring(0, 1);
        int xmapid = Integer.parseInt(tpclid.substring(1, 3));
        // Get the origin point
        point = getOriginPoint(tempString, xmapid);
        if (point == null)
        {
            return null;
        }
        tempString = tpclid.substring(1, 5);
        width = SX1200;
        height = SY1200;
        tempPoint = twoNumberScale(tempString, 800, 500);
        if (tempPoint != null)
        {
            point.x = (point.x + tempPoint.x);
            point.y = (point.y + tempPoint.y);
        }
        if (tpclid.length() >= 7)
        {
            tempString = (asciiToInt(tpclid.substring(5, 6)) - 65) + "" + (asciiToInt(tpclid.substring(6, 7)) - 65);
            tempPoint = twoNumberScale(tempString, 100);
            if (tempPoint != null)
            {
                point.x = point.x + tempPoint.x;
                point.y = point.y + tempPoint.y;
            }
            width = 100.0;
            height = 100.0;
        }
        if (tpclid.length() >= 9)
        {
            tempString = tpclid.substring(7, 8);
            tempPoint = twoNumberScale(tempString, 10);
            if (tempPoint != null)
            {
                point.x = point.x + tempPoint.x;
                point.y = point.y + tempPoint.y;
            }
            width = 10.0;
            height = 10.0;
        }
        if (tpclid.length() >= 11)
        {
            tempString = tpclid.substring(10);
            tempPoint = twoNumberScale(tempString, 1);
            if (tempPoint != null)
            {
                point.x = point.x + tempPoint.x;
                point.y = point.y + tempPoint.y;
            }
            width = 1.0;
            height = 1.0;
        }
        Coordinate pt2 = new Coordinate(point);
        pt2.x += width;
        pt2.y += height;
        return  new Envelope(point, pt2);
    }
    public static Coordinate convertTpclIdToCoordinate(String tpclid)
    {
        String tempString = "";
        Coordinate point = null;
        Coordinate tempPoint = null;
        if (tpclid.length() < 5)
        {
            return null;
        }
        tempString = tpclid.substring(0, 1);
        int xmapid = Integer.parseInt(tpclid.substring(1, 3));
        // Get the origin point
        point = getOriginPoint(tempString, xmapid);
        if (point == null)
        {
            return null;
        }
        tempString = tpclid.substring(1, 5);
        tempPoint = twoNumberScale(tempString, 800, 500);
        if (tempPoint != null)
        {
            point.x = (point.x + tempPoint.x);
            point.y = (point.y + tempPoint.y);
        }
        if (tpclid.length() >= 7)
        {
            tempString = (asciiToInt(tpclid.substring(5, 6)) - 65) + "" + (asciiToInt(tpclid.substring(6, 7)) - 65);
            tempPoint = twoNumberScale(tempString, 100);
            if (tempPoint != null)
            {
                point.x = point.x + tempPoint.x;
                point.y = point.y + tempPoint.y;
            }
        }
        if (tpclid.length() >= 9)
        {
            tempString = tpclid.substring(7, 9);
            tempPoint = twoNumberScale(tempString, 10);
            if (tempPoint != null)
            {
                point.x = point.x + tempPoint.x;
                point.y = point.y + tempPoint.y;
            }
        }
        if (tpclid.length() >= 11)
        {
            tempString = tpclid.substring(10);
            tempPoint = twoNumberScale(tempString, 1);
            if (tempPoint != null)
            {
                point.x = point.x + tempPoint.x;
                point.y = point.y + tempPoint.y;
            }
        }
        return point;
    }
    private static int intDivision(double p1, int p2)
    {
        double resultValue = 0.0;
        String result;
        resultValue = p1 / p2;
        result = Double.toString(resultValue);
        String[] temp = StringUtils.splitToArray(result, ".");
        result = temp[0];
        return Integer.parseInt(result);
    }
    private static Coordinate twoNumberScale(String number, int scaleX, int scaleY)
    {
        Coordinate tempPoint = new Coordinate();
        if (number.length() == 2)
        {
            tempPoint.x = Double.parseDouble(number.substring(0, 1)) * scaleX;
            tempPoint.y = Double.parseDouble(number.substring(1, 2)) * scaleY;
        } else if (number.length() == 1)
        {
            tempPoint.x = Double.parseDouble(number.substring(0, 1)) * scaleX;
            tempPoint.y = 0;
        } else if (number.length() == 4)
        {
            tempPoint.x = Double.parseDouble(number.substring(0, 2)) * scaleX;
            tempPoint.y = Double.parseDouble(number.substring(2, 4)) * scaleY;
        } else
        {
            tempPoint.x = 0;
            tempPoint.y = 0;
        }
        return tempPoint;
    }
    private static int asciiToInt(String p1)
    {
        if (p1.endsWith("A")) return 65;
        if (p1.endsWith("B")) return 66;
        if (p1.endsWith("C")) return 67;
        if (p1.endsWith("D")) return 68;
        if (p1.endsWith("E")) return 69;
        if (p1.endsWith("F")) return 70;
        if (p1.endsWith("G")) return 71;
        if (p1.endsWith("H")) return 72;
        if (p1.endsWith("I")) return 73;
        if (p1.endsWith("J")) return 74;
        if (p1.endsWith("K")) return 75;
        if (p1.endsWith("L")) return 76;
        if (p1.endsWith("M")) return 77;
        if (p1.endsWith("N")) return 78;
        if (p1.endsWith("O")) return 79;
        if (p1.endsWith("P")) return 80;
        if (p1.endsWith("Q")) return 81;
        if (p1.endsWith("R")) return 82;
        if (p1.endsWith("S")) return 83;
        if (p1.endsWith("T")) return 84;
        if (p1.endsWith("U")) return 85;
        if (p1.endsWith("V")) return 86;
        if (p1.endsWith("W")) return 87;
        if (p1.endsWith("X")) return 88;
        if (p1.endsWith("Y")) return 89;
        if (p1.endsWith("Z")) return 90;
        return 0;
    }
    private static char intToAscii(int p1)
    {
        switch (p1)
        {
        case 65:
            return 'A';
        case 66:
            return 'B';
        case 67:
            return 'C';
        case 68:
            return 'D';
        case 69:
            return 'E';
        case 70:
            return 'F';
        case 71:
            return 'G';
        case 72:
            return 'H';
        case 73:
            return 'I';
        case 74:
            return 'J';
        case 75:
            return 'K';
        case 76:
            return 'L';
        case 77:
            return 'M';
        case 78:
            return 'N';
        case 79:
            return 'O';
        case 80:
            return 'P';
        case 81:
            return 'Q';
        case 82:
            return 'R';
        case 83:
            return 'S';
        case 84:
            return 'T';
        case 85:
            return 'U';
        case 86:
            return 'V';
        case 87:
            return 'W';
        case 88:
            return 'X';
        case 89:
            return 'Y';
        case 90:
            return 'Z';
        default:
            return '1';
        }
    }
    private static Coordinate getOriginPoint(String letter, int xMapId)
    {
        int aSwitch = asciiToInt(letter);
        Coordinate Point = new Coordinate();
        switch (aSwitch)
        {
        case 65: //A
        {
            Point.x = 170000;
            Point.y = 2750000;
            break;
        }
        case 66: //B
        {
            Point.x = 250000;
            Point.y = 2750000;
            break;
        }
        case 67: //C
        {
            Point.x = 330000;
            Point.y = 2750000;
            break;
        }
        case 68: //D
        {
            Point.x = 170000;
            Point.y = 2700000;
            break;
        }
        case 69: //E
        {
            Point.x = 250000;
            Point.y = 2700000;
            break;
        }
        case 70: //F
        {
            Point.x = 330000;
            Point.y = 2700000;
            break;
        }
        case 71: //G
        {
            Point.x = 170000;
            Point.y = 2650000;
            break;
        }
        case 72: //H
        {
            Point.x = 250000;
            Point.y = 2650000;
            break;
        }
        case 73: //I
        {
            Point.x = 330000;
            Point.y = 2650000;
            break;
        }
        case 74: //J
        {
            Point.x = 90000;
            Point.y = 2600000;
            break;
        }
        case 75: //K
        {
            Point.x = 170000;
            Point.y = 2600000;
            break;
        }
        case 76: //L
        {
            Point.x = 250000;
            Point.y = 2600000;
            break;
        }
        case 77: //M
        {
            Point.x = 90000;
            Point.y = 2550000;
            break;
        }
        case 78: //N
        {
            Point.x = 170000;
            Point.y = 2550000;
            break;
        }
        case 79: //O
        {
            Point.x = 250000;
            Point.y = 2550000;
            break;
        }
        case 80: //P
        {
            Point.x = 90000;
            Point.y = 2500000;
            break;
        }
        case 81: //Q
        {
            Point.x = 170000;
            Point.y = 2500000;
            break;
        }
        case 82: //R
        {
            Point.x = 250000;
            Point.y = 2500000;
            break;
        }
        case 83: //°¨¯ª S
        {
            Point.x = 10000;
            Point.y = 2894000;
            break;
        }
        case 84: //T
        {
            Point.x = 170000;
            Point.y = 2450000;
            break;
        }
        case 85: //U
        {
            Point.x = 250000;
            Point.y = 2450000;
            break;
        }
        case 86: //V
        {
            Point.x = 170000;
            Point.y = 2400000;
            break;
        }
        case 87: // W
        {
            Point.x = 250000;
            Point.y = 2400000;
            break;
        }
        case 88: //¼ê´ò X
        {
            Point.x = 10000;
            Point.y = 2614000;
            break;
        }
        case 89: //¼ê´ò Y
        {
            Point.x = 10000;
            Point.y = 2564000;
            break;
        }
        case 90: //ª÷ªù ¥ªZ
        {
            Point.x = (xMapId < 51) ? 90000 : 10000;
            Point.y = 2675800;
            break;
        }
        default:
        {
            return null;
        }
        }
        return Point;
    }
    private static Coordinate twoNumberScale(String number, int scale)
    {
        return twoNumberScale(number, scale, scale);
    }
    private static String dataFormat(int p1)
    {
        String s1 = Integer.toString(p1);
        if (s1.length() < 2)
            s1 = "0" + s1;
        return s1;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWDDatumConverter.java
New file
@@ -0,0 +1,508 @@
package com.ximple.eofms.util;
import com.vividsolutions.jts.geom.Coordinate;
/**
 * TWDDatumConverter
 * User: Ulysses
 * Date: 2007/10/8
 * Time: ¤U¤È 01:35:03
 * To change this template use File | Settings | File Templates.
 */
public abstract class TWDDatumConverter
{
    /*
     *   Definition of math related value
     */
    private static final double COS67_5 = 0.3826834323650897717284599840304e0;
    private static final double PI      = 3.14159265358979323e0;
    private static final double HALF_PI = 1.570796326794896615e0;
    private static final double DEG_RAD = 0.01745329251994329572e0;
    private static final double RAD_DEG = 57.295779513082321031e0;
    /*
     * Definition of datum related value
     */
    private static final double AD_C       = 1.0026000e0;
    private static final double TWD67_A    = 6378160.0e0;
    private static final double TWD67_B    = 6356774.7192e0;
    private static final double TWD67_ECC  = 0.00669454185458e0;
    private static final double TWD67_ECC2 = 0.00673966079586e0;
    // different from garmin and already knowned value, but those all value only
    private static final double TWD67_DX = -752.32e0;
    // got 5-15m accuracy. the real offical value is holded by somebody and not
    private static final double TWD67_DY = -361.32e0;
    // release to public. if can got more enough twd67/twd97 control point coordinare,
    private static final double TWD67_DZ   = -180.51e0;
    private static final double TWD67_RX   = -0.00000117e0;    // then we can calculate a better value than now.
    private static final double TWD67_RY   = 0.00000184e0;     //
    private static final double TWD67_RZ   = 0.00000098e0;     // and, also lack twd67/twd97 altitude convertion value...
    private static final double TWD67_S    = 0.00002329e0;     //
    private static final double TWD97_A    = 6378137.0e0;
    private static final double TWD97_B    = 6356752.3141e0;
    private static final double TWD97_ECC  = 0.00669438002290e0;
    private static final double TWD97_ECC2 = 0.00673949677556e0;
    private static final double TWD67_TM2  = 0.9999e0;         // TWD67->TM2 scale
    private static final double TWD97_TM2  = 0.9999e0;         // TWD97->TM2 scale
    /*
     * datum convert function
     */
    public static Coordinate toTWD97(Coordinate pt)
    {
        double newX, newY, newZ;
        double r, pole, sin_lat, cos_lat;
        double lat, lon, height;
        double x1, y1, z1, x2, y2, z2;
        double q, q2, t, t1, s, s1, sum, sin_b, cos_b, sin_p, cos_p;
        lon    = pt.x * DEG_RAD;
        lat    = pt.y * DEG_RAD;
        height = pt.z * DEG_RAD;
        if ((lat < -HALF_PI) && (lat > -1.001 * HALF_PI))
        {
            lat = -HALF_PI;
        } else if ((lat > HALF_PI) && (lat < 1.001 * HALF_PI))
        {
            lat = HALF_PI;
        } else if ((lat < -HALF_PI) || (lat > HALF_PI))
        {
            return null;
        }
        if (lon > PI)
        {
            lon -= (2 * PI);
        }
        sin_lat = Math.sin(lat);
        cos_lat = Math.cos(lat);
        r       = TWD67_A / (Math.sqrt(1.0 - TWD67_ECC * sin_lat * sin_lat));
        x1      = (r + height) * cos_lat * Math.cos(lon);
        y1      = (r + height) * cos_lat * Math.sin(lon);
        z1      = ((r * (1 - TWD67_ECC)) + height) * sin_lat;
        x2      = x1 + TWD67_DX + TWD67_S * (lon + TWD67_RZ * lat - TWD67_RY * height);
        y2      = y1 + TWD67_DY + TWD67_S * (-TWD67_RZ * lon + lat + TWD67_RX * height);
        z2      = z1 + TWD67_DZ + TWD67_S * (TWD67_RY * lon - TWD67_RX * lat + height);
        pole    = 0.0;
        if (x2 != 0.0)
        {
            lon = Math.atan2(y2, x2);
        } else
        {
            if (y2 > 0)
            {
                lon = HALF_PI;
            } else if (y2 < 0)
            {
                lon = -HALF_PI;
            } else
            {
                pole = 1;
                lon  = 0;
                if (z2 > 0)
                {
                    lat = HALF_PI;
                } else if (z2 < 0)
                {
                    lat = -HALF_PI;
                } else
                {
                    lat  = HALF_PI;
                    newX = lon * RAD_DEG;
                    newY = lat * RAD_DEG;
                    newZ = -TWD97_B;
                    return new Coordinate(newX, newY, newZ);
                }
            }
        }
        q2    = x2 * x2 + y2 * y2;
        q     = Math.sqrt(q2);
        t     = z2 * AD_C;
        s     = Math.sqrt(t * t + q2);
        sin_b = t / s;
        cos_b = q / s;
        t1    = z2 + TWD97_B * TWD97_ECC2 * sin_b * sin_b * sin_b;
        sum   = q - TWD97_A * TWD97_ECC * cos_b * cos_b * cos_b;
        s1    = Math.sqrt(t1 * t1 + sum * sum);
        sin_p = t1 / s1;
        cos_p = sum / s1;
        r     = TWD97_A / Math.sqrt(1.0 - TWD97_ECC * sin_p * sin_p);
        if (cos_p >= COS67_5)
        {
            height = q / cos_p - r;
        } else if (cos_p <= -COS67_5)
        {
            height = q / -cos_p - r;
        } else
        {
            height = z2 / sin_p + r * (TWD97_ECC - 1.0);
        }
        if (pole !=0.0)
        {
            lat = Math.atan(sin_p / cos_p);
        }
        newX = lon * RAD_DEG;
        newY = lat * RAD_DEG;
        newZ = height;
        return new Coordinate(newX, newY, newZ);
    }
    public static Coordinate toTWD67(Coordinate pt)
    {
        double newX, newY, newZ;
        double r, pole, sin_lat, cos_lat;
        double lat, lon, height;
        double x1, y1, z1, x2, y2, z2;
        double q, q2, t, t1, s, s1, sum, sin_b, cos_b, sin_p, cos_p;
        lon    = pt.x * DEG_RAD;
        lat    = pt.y * DEG_RAD;
        height = pt.z * DEG_RAD;
        if ((lat < -HALF_PI) && (lat > -1.001 * HALF_PI))
        {
            lat = -HALF_PI;
        } else if ((lat > HALF_PI) && (lat < 1.001 * HALF_PI))
        {
            lat = HALF_PI;
        } else if ((lat < -HALF_PI) || (lat > HALF_PI))
        {
            return null;
        }
        if (lon > PI)
        {
            lon -= (2 * PI);
        }
        sin_lat = Math.sin(lat);
        cos_lat = Math.cos(lat);
        r       = TWD97_A / (Math.sqrt(1.0 - TWD97_ECC * sin_lat * sin_lat));
        x1      = (r + height) * cos_lat * Math.cos(lon);
        y1      = (r + height) * cos_lat * Math.sin(lon);
        z1      = ((r * (1 - TWD97_ECC)) + height) * sin_lat;
        x2      = x1 - TWD67_DX - TWD67_S * (lon + TWD67_RZ * lat - TWD67_RY * height);
        y2      = y1 - TWD67_DY - TWD67_S * (-TWD67_RZ * lon + lat + TWD67_RX * height);
        z2      = z1 - TWD67_DZ - TWD67_S * (TWD67_RY * lon - TWD67_RX * lat + height);
        pole    = 0;
        if (x2 != 0.0)
        {
            lon = Math.atan2(y2, x2);
        } else
        {
            if (y2 > 0)
            {
                lon = HALF_PI;
            } else if (y2 < 0)
            {
                lon = -HALF_PI;
            } else
            {
                pole = 1;
                lon  = 0;
                if (z2 > 0)
                {
                    lat = HALF_PI;
                } else if (z2 < 0)
                {
                    lat = -HALF_PI;
                } else
                {
                    lat  = HALF_PI;
                    newX = lon * RAD_DEG;
                    newY = lat * RAD_DEG;
                    newZ = -TWD67_B;
                    return new Coordinate(newX, newY, newZ);
                }
            }
        }
        q2    = x2 * x2 + y2 * y2;
        q     = Math.sqrt(q2);
        t     = z2 * AD_C;
        s     = Math.sqrt(t * t + q2);
        sin_b = t / s;
        cos_b = q / s;
        t1    = z2 + TWD67_B * TWD67_ECC2 * sin_b * sin_b * sin_b;
        sum   = q - TWD67_A * TWD67_ECC * cos_b * cos_b * cos_b;
        s1    = Math.sqrt(t1 * t1 + sum * sum);
        sin_p = t1 / s1;
        cos_p = sum / s1;
        r     = TWD67_A / Math.sqrt(1.0 - TWD67_ECC * sin_p * sin_p);
        if (cos_p >= COS67_5)
        {
            height = q / cos_p - r;
        } else if (cos_p <= -COS67_5)
        {
            height = q / -cos_p - r;
        } else
        {
            height = z2 / sin_p + r * (TWD67_ECC - 1.0);
        }
        if (pole != 0.0)
        {
            lat = Math.atan(sin_p / cos_p);
        }
        newX = lon * RAD_DEG;
        newY = lat * RAD_DEG;
        newZ = height;
        return new Coordinate(newX, newY, newZ);
    }
    public static Coordinate toTM2(double a, double ecc, double ecc2, double lat, double lon, double scale, double x, double y)
    {
        double x0, y0, x1, y1, m0, m1;
        double n, t, c, A;
        double newX, newY;
        x0   = x * DEG_RAD;
        y0   = y * DEG_RAD;
        x1   = lon * DEG_RAD;
        y1   = lat * DEG_RAD;
        m0   = mercator(y1, a, ecc);
        m1   = mercator(y0, a, ecc);
        n    = a / Math.sqrt(1 - ecc * Math.pow(Math.sin(y0), 2.0));
        t    = Math.pow(Math.tan(y0), 2.0);
        c    = ecc2 * Math.pow(Math.cos(y0), 2.0);
        A    = (x0 - x1) * Math.cos(y0);
        newX = scale * n
               * (A + (1.0 - t + c) * A * A * A / 6.0
                  + (5.0 - 18.0 * t + t * t + 72.0 * c - 58.0 * ecc2) * Math.pow(A, 5.0) / 120.0);
        newY = scale
               * (m1 - m0
                  + n * Math.tan(y0)
                    * (A * A / 2.0 + (5.0 - t + 9.0 * c + 4 * c * c) * Math.pow(A, 4.0) / 24.0
                       + (61.0 - 58.0 * t + t * t + 600.0 * c - 330.0 * ecc2) * Math.pow(A, 6.0) / 720.0));
        return new Coordinate(newX, newY);
    }
    public static Coordinate fromTM2(double a, double ecc, double ecc2, double lat, double lon, double scale, double x, double y)
    {
        double newX, newY;
        double x0, y0, x1, y1, phi, m, m0, mu, e1;
        double c1, t1, n1, r1, d;
        x0  = x;
        y0  = y;
        x1  = lon * DEG_RAD;
        y1  = lat * DEG_RAD;
        m0  = mercator(y1, a, ecc);
        m   = m0 + y0 / scale;
        e1  = (1.0 - Math.sqrt(1.0 - ecc)) / (1.0 + Math.sqrt(1.0 - ecc));
        mu  = m / (a * (1.0 - ecc / 4.0 - 3.0 * ecc * ecc / 64.0 - 5.0 * ecc * ecc * ecc / 256.0));
        phi = mu + (3.0 * e1 / 2.0 - 27.0 * Math.pow(e1, 3.0) / 32.0) * Math.sin(2.0 * mu)
              + (21.0 * e1 * e1 / 16.0 - 55.0 * Math.pow(e1, 4.0) / 32.0) * Math.sin(4.0 * mu)
              + 151.0 * Math.pow(e1, 3.0) / 96.0 * Math.sin(6.0 * mu) + 1097.0 * Math.pow(e1, 4.0) / 512.0 * Math.sin(8.0 * mu);
        c1   = ecc2 * Math.pow(Math.cos(phi), 2.0);
        t1   = Math.pow(Math.tan(phi), 2.0);
        n1   = a / Math.sqrt(1 - ecc * Math.pow(Math.sin(phi), 2.0));
        r1   = a * (1.0 - ecc) / Math.pow(1.0 - ecc * Math.pow(Math.sin(phi), 2.0), 1.5);
        d    = x0 / (n1 * scale);
        newX = (x1 + (d - (1.0 + 2.0 * t1 + c1) * Math.pow(d, 3.0) / 6.0
                      + (5.0 - 2.0 * c1 + 28.0 * t1 - 3.0 * c1 * c1 + 8.0 * ecc2 + 24.0 * t1 * t1) * Math.pow(d, 5.0)
                        / 120.0) / Math.cos(phi)) * RAD_DEG;
        newY = (phi
                - n1 * Math.tan(phi) / r1
                  * (d * d / 2.0 - (5.0 + 3.0 * t1 + 10.0 * c1 - 4.0 * c1 * c1 - 9.0 * ecc2) * Math.pow(d, 4.0) / 24.0
                     + (61.0 + 90.0 * t1 + 298.0 * c1 + 45.0 * t1 * t1 - 252.0 * ecc2 - 3.0 * c1 * c1) * Math.pow(d, 6.0)
                       / 72.0)) * RAD_DEG;
        return new Coordinate(newX, newY);
    }
    private static double mercator(double y, double a, double ecc)
    {
        if (y == 0.0)
        {
            return 0.0;
        } else
        {
            return a * ((1.0 - ecc / 4.0 - 3.0 * ecc * ecc / 64.0 - 5.0 * ecc * ecc * ecc / 256.0) * y
                        - (3.0 * ecc / 8.0 + 3.0 * ecc * ecc / 32.0 + 45.0 * ecc * ecc * ecc / 1024.0) * Math.sin(2.0 * y)
                        + (15.0 * ecc * ecc / 256.0 + 45.0 * ecc * ecc * ecc / 1024.0) * Math.sin(4.0 * y)
                        - (35.0 * ecc * ecc * ecc / 3072.0) * Math.sin(6.0 * y));
        }
    }
    /**
     *
     *  Sample code below, using coordinate in Dan Jacob's website.
     *
     *
     * int main()
     * {
     *   double x1, y1, z1, x2, y2, z2;
     *   double tx1, ty1, tx2, ty2;
     *   double dx, dy, dz, dx1, dy1;
     *
     *   x1 = 120.85788004;          // TWD67
     *   y1 = 24.18347242;
     *   z1 = 777;
     *
     *   x2 = 120.86603958;          // TWD97
     *   y2 = 24.18170479;
     *   z2 = 777;
     *
     *   tx1 = 235561;               // TWD67->TM2
     *   ty1 = 2675359;
     *
     *   tx2 = 236389.849;           // TWD97->TM2
     *   ty2 = 2675153.168;
     *
     *   ////////////////////////////////////////////
     *   /
     *   /
     *   // convert TWD67->TM2
     *   /
     *   /
     *   ////////////////////////////////////////////
     *
     *   dx = x1;
     *   dy = y1;
     *
     *   toTM2(TWD67_A, TWD67_ECC, TWD67_ECC2, 0, 121, TWD67_TM2, &dx, &dy);
     *   // center longitude of taiwan is 121, for penghu is 119
     *
     *   dx += 250000;   // TM2 in Taiwan should add 250000
     *
     *   printf("TWD67->TM2nTWD67   (%f, %f)nConvert (%.3f, %.3f)nOrigin  (%.3f, %.3f)n", x1, y1, dx, dy, tx1, ty1);
     *   printf("Acuuracy (%.3f, X:%.3f, Y:%.3f)nn", sqrt((dx-tx1)*(dx-tx1)+(dy-ty1)*(dy-ty1)), (dx-tx1), (dy-ty1));
     *
     *   ////////////////////////////////////////////
     *   /
     *   /
     *   // convert TWD97->TM2
     *   /
     *   /
     *   ////////////////////////////////////////////
     *
     *   dx = x2;
     *   dy = y2;
     *
     *   toTM2(TWD97_A, TWD97_ECC, TWD97_ECC2, 0, 121, TWD97_TM2, &dx, &dy);
     *   // center longitude of taiwan is 121, for penghu is 119
     *
     *   dx += 250000;   // TM2 in Taiwan should add 250000
     *
     *   printf("TWD97->TM2nTWD97   (%f, %f)nConvert (%.3f, %.3f)nOrigin  (%.3f, %.3f)n", x2, y2, dx, dy, tx2, ty2);
     *   printf("Acuuracy (%.3f, X:%.3f, Y:%.3f)nn", sqrt((dx-tx2)*(dx-tx2)+(dy-ty2)*(dy-ty2)), (dx-tx2), (dy-ty2));
     *
     *   ////////////////////////////////////////////
     *   /
     *   /
     *   // convert TM2->TWD67
     *   /
     *   /
     *   ////////////////////////////////////////////
     *
     *   dx = tx1-250000;    // should minus 250000 first in Taiwan
     *   dy = ty1;
     *
     *   fromTM2(TWD67_A, TWD67_ECC, TWD67_ECC2, 0, 121, TWD67_TM2, &dx, &dy);
     *
     *   printf("TM2->TWD67nTM2     (%f, %f)nConvert (%.9f, %.9f)nOrigin  (%.9f, %.9f)n", tx1, ty1, dx, dy, x1, y1);
     *   printf("Acuuracy (%.9f, X:%.9f, Y:%.9f)nn", sqrt((dx-x1)*(dx-x1)+(dy-y1)*(dy-y1)), (dx-x1), (dy-y1));
     *
     *   ////////////////////////////////////////////
     *   /
     *   /
     *   // convert TM2->TWD97
     *   /
     *   /
     *   ////////////////////////////////////////////
     *
     *   dx = tx2-250000;    // should minus 250000 first in Taiwan
     *   dy = ty2;
     *
     *   fromTM2(TWD97_A, TWD97_ECC, TWD97_ECC2, 0, 121, TWD97_TM2, &dx, &dy);
     *
     *   printf("TM2->TWD97nTM2     (%f, %f)nConvert (%.9f, %.9f)\nOrigin  (%.9f, %.9f)\n", tx2, ty2, dx, dy, x2, y2);
     *   printf("Acuuracy (%.9f, X:%.9f, Y:%.9f)nn", sqrt((dx-x2)*(dx-x2)+(dy-y2)*(dy-y2)), (dx-x2), (dy-y2));
     *
     *   ////////////////////////////////////////////
     *   /
     *   /
     *   // convert TWD67->TWD97
     *   /
     *   /
     *   ////////////////////////////////////////////
     *
     *   dx = x1;
     *   dy = y1;
     *   dz = z1;
     *
     *   toTWD97(&dx, &dy, &dz);
     *
     *   dx1 = dx;
     *   dy1 = dy;
     *
     *   toTM2(TWD97_A, TWD97_ECC, TWD97_ECC2, 0, 121, TWD97_TM2, &dx1, &dy1);
     *
     *   dx1 += 250000;  // TM2 in Taiwan should add 250000
     *
     *   printf("TWD67->TWD97\nTWD67   (%.9f, %.9f, %6.2f) (%.3f, %.3f)n", x1, y1, z1, tx1, ty1);
     *   printf("Convert (%.9f, %.9f, %6.2f) (%.3f, %.3f)n", dx, dy, dz, dx1, dy1);
     *   printf("Origin  (%.9f, %.9f, %6.2f) (%.3f, %.3f)n", x2, y2, z2, tx2, ty2);
     *   printf("Acuuracy (%.4f, X:%.4f, Y:%.4f)nn", sqrt((dx1-tx2)*(dx1-tx2)+(dy1-ty2)*(dy1-ty2)), (dx1-tx2), (dy1-ty2));
     *
     *   ////////////////////////////////////////////
     *   /
     *   /
     *   // convert TWD97->TWD67
     *   /
     *   /
     *   ////////////////////////////////////////////
     *
     *   dx = x2;
     *   dy = y2;
     *   dz = z2;
     *
     *   toTWD67(&dx, &dy, &dz);
     *
     *   dx1 = dx;
     *   dy1 = dy;
     *
     *   toTM2(TWD67_A, TWD67_ECC, TWD67_ECC2, 0, 121, TWD67_TM2, &dx1, &dy1);
     *
     *   dx1 += 250000;  // TM2 in Taiwan should add 250000
     *
     *   printf("TWD97->TWD67nTWD97   (%.9f, %.9f, %6.2f) (%.3f, %.3f)n", x2, y2, z2, tx2, ty2);
     *   printf("Convert (%.9f, %.9f, %6.2f) (%.3f, %.3f)n", dx, dy, dz, dx1, dy1);
     *   printf("Origin  (%.9f, %.9f, %6.2f) (%.3f, %.3f)n", x1, y1, z1, tx1, ty1);
     *   printf("Acuuracy (%.4f, X:%.4f, Y:%.4f)nn", sqrt((dx1-tx1)*(dx1-tx1)+(dy1-ty1)*(dy1-ty1)), (dx1-tx1), (dy1-ty1));
     * }
     */
    /**
     * ¥ÑTM2®y¼ÐÂà´«¦ÜTWD97®y¼Ð
     * @param pt TM2¦ì¸m
     * @return ·sªºTWD97®y¼Ð
     */
    public static Coordinate fromTM2ToTWD97(Coordinate pt)
    {
        Coordinate ptTWD67 = fromTM2(TWD67_A, TWD67_ECC, TWD67_ECC2, 0, 121, TWD67_TM2, pt.x - 250000.0, pt.y);
        ptTWD67.z = 0;
        Coordinate ptTWD97 = toTWD97(ptTWD67);
        Coordinate pt97TM2 = toTM2(TWD97_A, TWD97_ECC, TWD97_ECC2, 0, 121, TWD97_TM2, ptTWD97.x, ptTWD97.y);
        pt97TM2.x += 250000.0;
        pt97TM2.y -= 200.0;
        return pt97TM2;
    }
}
xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/ElementDispatcherRules.xml
New file
@@ -0,0 +1,161 @@
<?xml version='1.0' encoding="big5"?>
<!DOCTYPE digester-rules PUBLIC "-//Jakarta Apache //DTD digester-rules XML V1.0//EN" "digester-rules.dtd">
<digester-rules>
  <pattern value="ElementDispatcherRules">
    <object-create-rule classname="com.ximple.eofms.filter.ElementDispatcher"/>
    <set-properties-rule/>
    <pattern value="TypeFilter">
      <object-create-rule classname="com.ximple.eofms.filter.TypeIdDispatchableFilter"/>
      <set-next-rule methodname="addRule" paramtype="com.ximple.eofms.filter.ElementDispatchableFilter"/>
      <set-properties-rule/>
      <bean-property-setter-rule pattern="name"/>
      <bean-property-setter-rule pattern="description"/>
      <bean-property-setter-rule pattern="elmtype"/>
      <bean-property-setter-rule pattern="tid"/>
      <pattern value="LineCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateLineStringStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="TextCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateTextStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="SymbolCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateSymbolStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="LineTextCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateLineTextStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="ShapeCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateShapeStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="ArcLineCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateArcLineStringStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="EllipseShapeCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateEllipseShapeStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
    </pattern>
    <pattern value="TypeCompFilter">
      <object-create-rule classname="com.ximple.eofms.filter.TypeCompIdDispatchableFilter"/>
      <set-next-rule methodname="addRule" paramtype="com.ximple.eofms.filter.ElementDispatchableFilter"/>
      <set-properties-rule/>
      <bean-property-setter-rule pattern="name"/>
      <bean-property-setter-rule pattern="description"/>
      <!-- <bean-property-setter-rule pattern="elmtype"/> -->
      <bean-property-setter-rule pattern="tid"/>
      <bean-property-setter-rule pattern="cid"/>
      <pattern value="elementCriterion">
        <object-create-rule classname="com.ximple.eofms.filter.ElementTypeCriterion"/>
        <set-next-rule methodname="addCriterion" paramtype="com.ximple.eofms.filter.ElementTypeCriterion"/>
        <set-properties-rule/>
        <bean-property-setter-rule pattern="elementType"/>
      </pattern>
      <pattern value="LineCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateLineStringStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="TextCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateTextStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="SymbolCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateSymbolStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="LineTextCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateLineTextStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="ShapeCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateShapeStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="ArcLineCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateArcLineStringStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="EllipseShapeCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateEllipseShapeStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
    </pattern>
    <pattern value="TypeCompLevelFilter">
      <object-create-rule classname="com.ximple.eofms.filter.TypeCompLevelIdDispatchableFilter"/>
      <set-next-rule methodname="addRule" paramtype="com.ximple.eofms.filter.ElementDispatchableFilter"/>
      <set-properties-rule/>
      <bean-property-setter-rule pattern="name"/>
      <bean-property-setter-rule pattern="description"/>
      <!-- <bean-property-setter-rule pattern="elmtype"/> -->
      <bean-property-setter-rule pattern="tid"/>
      <bean-property-setter-rule pattern="cid"/>
      <!-- <bean-property-setter-rule pattern="lid"/> -->
      <pattern value="elementCriterion">
        <object-create-rule classname="com.ximple.eofms.filter.ElementTypeCriterion"/>
        <set-next-rule methodname="addCriterion" paramtype="com.ximple.eofms.filter.ElementTypeCriterion"/>
        <set-properties-rule/>
        <bean-property-setter-rule pattern="elementType"/>
      </pattern>
      <pattern value="elementLayerCriterion">
        <object-create-rule classname="com.ximple.eofms.filter.ElementLevelCriterion"/>
        <set-next-rule methodname="addLayerCriterion" paramtype="com.ximple.eofms.filter.ElementLevelCriterion"/>
        <set-properties-rule/>
        <bean-property-setter-rule pattern="elementLayer"/>
      </pattern>
      <pattern value="LineCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateLineStringStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="TextCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateTextStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="SymbolCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateSymbolStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="LineTextCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateLineTextStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="ShapeCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateShapeStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="ArcLineCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateArcLineStringStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
      <pattern value="EllipseShapeCreateStrategy">
        <object-create-rule classname="com.ximple.eofms.filter.CreateEllipseShapeStrategy"/>
        <set-next-rule methodname="setCreateStrategy" paramtype="com.ximple.eofms.filter.CreateFeatureTypeStrategy"/>
        <set-properties-rule/>
      </pattern>
    </pattern>
  </pattern>
</digester-rules>
xdgnjobs/ximple-spatialjob/src/main/resources/conf/ConvertShpFilterForLayer.xml
New file
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="big5" ?>
<ElementDispatcherRules>
  <!-- High Voltage Features -->
  <TypeCompLevelFilter name="FSC-106.C-0">
    <tid>106</tid>
    <cid>0</cid>
    <description>¥D°ªÀ£½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <elementLevelCriterion>
      <elementLevel>1</elementLevel>
    </elementLevelCriterion>
    <LineCreateStrategy/>
  </TypeCompLevelFilter>
</ElementDispatcherRules>
xdgnjobs/ximple-spatialjob/src/main/resources/conf/DefaultConvertShpFilter.xml
New file
@@ -0,0 +1,1465 @@
<?xml version="1.0" encoding="big5" ?>
<ElementDispatcherRules>
  <!-- High Voltage Features -->
  <TypeCompFilter name="FSC-106.C-0">
    <tid>106</tid>
    <cid>0</cid>
    <description>¥D°ªÀ£½u</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-106.C-1">
    <tid>106</tid>
    <cid>1</cid>
    <description>°ªÀ£½u¤Þ½u</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-106.C-2">
    <tid>106</tid>
    <cid>2</cid>
    <description>°ªÀ£½u¤Þ½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-106.C-4">
    <tid>106</tid>
    <cid>4</cid>
    <description>°ªÀ£½uõX½u¥N¸¹¤Þ½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-402.C-0">
    <tid>402</tid>
    <cid>0</cid>
    <description>Åܹq©Ò</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-402.C-1">
    <tid>402</tid>
    <cid>1</cid>
    <description>Åܹq©Òµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-402.C-2">
    <tid>402</tid>
    <cid>2</cid>
    <description>Åܹq©Ò¤¤¤åµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-0">
    <tid>411</tid>
    <cid>0</cid>
    <description>°t¹q³õ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-1">
    <tid>411</tid>
    <cid>1</cid>
    <description>°t¹q³õµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-2">
    <tid>411</tid>
    <cid>2</cid>
    <description>°t¹q³õ-1/600</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-3">
    <tid>411</tid>
    <cid>3</cid>
    <description>°t¹q³õµù°O-1/600</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-7">
    <tid>411</tid>
    <cid>7</cid>
    <description>°t¹q³õ1/600¤Þ¤W¤U²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-420.C-0">
    <tid>420</tid>
    <cid>0</cid>
    <description>ºÞ·¾</description>
    <elementCriterion>
      <elementType>6</elementType>
    </elementCriterion>
    <ShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-420.C-1">
    <tid>420</tid>
    <cid>1</cid>
    <description>ºÞ·¾µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-421.C-0">
    <tid>421</tid>
    <cid>0</cid>
    <description>¦@¦PºÞ¹D</description>
    <elementCriterion>
      <elementType>6</elementType>
    </elementCriterion>
    <ShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-421.C-1">
    <tid>421</tid>
    <cid>1</cid>
    <description>¦@¦PºÞ¹Dµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-423.C-0">
    <tid>423</tid>
    <cid>0</cid>
    <description>ºÞ¸ôÂ_­±</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-423.C-1">
    <tid>423</tid>
    <cid>1</cid>
    <description>ºÞ¸ôÂ_­±¤Þ½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-424.C-0">
    <tid>424</tid>
    <cid>0</cid>
    <description>¯S®í¤uªkºX¼Ð²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-501.C-0">
    <tid>501</tid>
    <cid>0</cid>
    <description>»Ùê³òÆX</description>
    <elementCriterion>
      <elementType>6</elementType>
    </elementCriterion>
    <ShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-501.C-1">
    <tid>501</tid>
    <cid>1</cid>
    <description>»Ùê³òÆX¤å¦rµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-502.C-0">
    <tid>502</tid>
    <cid>0</cid>
    <description>°ÝÃD³òÆX</description>
    <elementCriterion>
      <elementType>6</elementType>
    </elementCriterion>
    <ShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-502.C-1">
    <tid>502</tid>
    <cid>1</cid>
    <description>°ÝÃD³òÆX¤å¦rµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-503.C-0">
    <tid>503</tid>
    <cid>0</cid>
    <description>¤å¦rµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-0">
    <tid>407</tid>
    <cid>0</cid>
    <description>¹q±ì</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-1">
    <tid>407</tid>
    <cid>1</cid>
    <description>¹q±ìµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-2">
    <tid>407</tid>
    <cid>2</cid>
    <description>¹q±ì-1/600</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-3">
    <tid>407</tid>
    <cid>3</cid>
    <description>¹q±ì-1/600µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-7">
    <tid>407</tid>
    <cid>7</cid>
    <description>1/600¹q±ì¤Þ¤W¤U²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-8">
    <tid>407</tid>
    <cid>8</cid>
    <description>1/1200¹q±ì¤Þ¤W¤U²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-9">
    <tid>407</tid>
    <cid>9</cid>
    <description>¹q±ì¤ô¥­¤ä½u</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <LineTextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-10">
    <tid>407</tid>
    <cid>10</cid>
    <description>¹q±ì±ì¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-11">
    <tid>407</tid>
    <cid>11</cid>
    <description>¹q±ì¤ô¥­¤ä½u³»»\</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-114.C-0">
    <tid>114</tid>
    <cid>0</cid>
    <description>¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-114.C-1">
    <tid>114</tid>
    <cid>1</cid>
    <description>¶}Ãö°j¸ôµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-114.C-2">
    <tid>114</tid>
    <cid>2</cid>
    <description>¶}Ãö¤p¬P¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-114.C-3">
    <tid>114</tid>
    <cid>3</cid>
    <description>¶}Ãö¤j¬P¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-122.C-0">
    <tid>122</tid>
    <cid>0</cid>
    <description>ª½±µ³s±µ</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <LineTextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-122.C-1">
    <tid>122</tid>
    <cid>1</cid>
    <description>ª½±µ³s±µµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-107.C-0">
    <tid>107</tid>
    <cid>0</cid>
    <description>°ªÀ£¥Î¤á</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-107.C-2">
    <tid>107</tid>
    <cid>2</cid>
    <description>°ªÀ£¥Î¤á¤¤¤åµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-117.C-0">
    <tid>117</tid>
    <cid>0</cid>
    <description>TieÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-105.C-0">
    <tid>105</tid>
    <cid>0</cid>
    <description>ª½¸ô±µÀY</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-105.C-1">
    <tid>105</tid>
    <cid>1</cid>
    <description>ª½¸ô±µÀYµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-101.C-0">
    <tid>101</tid>
    <cid>0</cid>
    <description>¶×¬y±Æ</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-120.C-0">
    <tid>120</tid>
    <cid>0</cid>
    <description>¸`ÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-150.C-0">
    <tid>150</tid>
    <cid>0</cid>
    <description>¨â¸ô¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-130.C-0">
    <tid>130</tid>
    <cid>0</cid>
    <description>¾É½u¥æ¤e</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-131.C-0">
    <tid>131</tid>
    <cid>0</cid>
    <description>¾É½uÅܧó</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-109.C-0">
    <tid>109</tid>
    <cid>0</cid>
    <description>¸õ½u³s±µ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-116.C-0">
    <tid>116</tid>
    <cid>0</cid>
    <description>°ªÀ£²×ºÝ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-108.C-0">
    <tid>108</tid>
    <cid>0</cid>
    <description>Â_¸ô¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-108.C-1">
    <tid>108</tid>
    <cid>1</cid>
    <description>Â_¸ô¾¹µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-119.C-0">
    <tid>119</tid>
    <cid>0</cid>
    <description>¹qÅæ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-0">
    <tid>115</tid>
    <cid>0</cid>
    <description>ÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-1">
    <tid>115</tid>
    <cid>1</cid>
    <description>ÅÜÀ£¾¹µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-2">
    <tid>115</tid>
    <cid>2</cid>
    <description>¸ô¿O¨t²Î¹ÏÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-3">
    <tid>115</tid>
    <cid>3</cid>
    <description>¸ô¿O¨t²Î¹ÏÅÜÀ£¾¹µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-4">
    <tid>115</tid>
    <cid>4</cid>
    <description>§CÀ£¨t²Î¹ÏÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-5">
    <tid>115</tid>
    <cid>5</cid>
    <description>§CÀ£¨t²Î¹ÏÅÜÀ£¾¹µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-6">
    <tid>115</tid>
    <cid>6</cid>
    <description>§CÀ£¨t²Î¹Ï-°t¹q«Ç®y¼Ðµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-7">
    <tid>115</tid>
    <cid>7</cid>
    <description>§CÀ£¨t²Î¹Ï-°t¹q«Ç®y¼Ðµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-8">
    <tid>115</tid>
    <cid>8</cid>
    <description>¬[ªÅÅÜÀ£¾¹(¦a¤U§CÀ£¥Î)µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-118.C-0">
    <tid>118</tid>
    <cid>0</cid>
    <description>¥DÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-102.C-0">
    <tid>102</tid>
    <cid>0</cid>
    <description>¹q®e¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-100.C-0">
    <tid>100</tid>
    <cid>0</cid>
    <description>Á×¹p¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-0">
    <tid>140</tid>
    <cid>0</cid>
    <description>°ªÀ£½u¸ô(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-1">
    <tid>140</tid>
    <cid>1</cid>
    <description>¤Þ½u(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-2">
    <tid>140</tid>
    <cid>2</cid>
    <description>¾É½uµù°O(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-3">
    <tid>140</tid>
    <cid>3</cid>
    <description>õX½u¥N¸¹¤Þ½u(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-4">
    <tid>140</tid>
    <cid>4</cid>
    <description>õX½u¥N¸¹µù°O(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-151.C-0">
    <tid>150</tid>
    <cid>0</cid>
    <description>±`³¬¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <!-- Low Voltage Features -->
  <TypeCompFilter name="FSC-200.C-0">
    <tid>200</tid>
    <cid>0</cid>
    <description>§CÀ£¸`ÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <!-- *****§CÀ£****** -->
  <TypeCompFilter name="FSC-201.C-0">
    <tid>201</tid>
    <cid>0</cid>
    <description>±µ¤á½u</description>
    <elementCriterion>
      <elementType>12</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-201.C-1">
    <tid>201</tid>
    <cid>1</cid>
    <description>±µ¤á½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-201.C-2">
    <tid>201</tid>
    <cid>2</cid>
    <description>±µ¤á½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-202.C-0">
    <tid>202</tid>
    <cid>0</cid>
    <description>±µ¤áÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-202.C-1">
    <tid>202</tid>
    <cid>1</cid>
    <description>±µ¤áÂIªùµPµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-203.C-0">
    <tid>203</tid>
    <cid>0</cid>
    <description>¸ô¿O³d¥ô¤À¬ÉÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-203.C-1">
    <tid>203</tid>
    <cid>1</cid>
    <description>¸ô¿O³d¥ô¤À¬ÉÂIµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-204.C-0">
    <tid>204</tid>
    <cid>0</cid>
    <description>§CÀ£¸õ½u</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-205.C-0">
    <tid>205</tid>
    <cid>0</cid>
    <description>§CÀ£¾É½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-205.C-1">
    <tid>205</tid>
    <cid>1</cid>
    <description>§CÀ£¾É½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-205.C-2">
    <tid>205</tid>
    <cid>2</cid>
    <description>§CÀ£¾É½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-206.C-0">
    <tid>206</tid>
    <cid>0</cid>
    <description>§CÀ£»»±±½c</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-206.C-1">
    <tid>206</tid>
    <cid>1</cid>
    <description>§CÀ£»»±±½cµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-206.C-2">
    <tid>206</tid>
    <cid>2</cid>
    <description>§CÀ£»»±±½cªùµPµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-207.C-0">
    <tid>207</tid>
    <cid>0</cid>
    <description>§CÀ£Äµ³ø¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-207.C-1">
    <tid>207</tid>
    <cid>1</cid>
    <description>§CÀ£Äµ³ø¾¹µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-207.C-2">
    <tid>207</tid>
    <cid>2</cid>
    <description>§CÀ£Äµ³ø¾¹ªùµPµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-208.C-0">
    <tid>208</tid>
    <cid>0</cid>
    <description>§CÀ£²×ºÝ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-209.C-0">
    <tid>209</tid>
    <cid>0</cid>
    <description>§CÀ£¥æ³q¸¹»x</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-209.C-1">
    <tid>209</tid>
    <cid>1</cid>
    <description>§CÀ£¥æ³q¸¹»xµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-0">
    <tid>210</tid>
    <cid>0</cid>
    <description>§CÀ£¦a¤U¾É½u</description>
    <elmtype>12</elmtype>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-1">
    <tid>210</tid>
    <cid>1</cid>
    <description>§CÀ£¦a¤U¾É½u¥´ÂI²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-2">
    <tid>210</tid>
    <cid>2</cid>
    <description>§CÀ£¦a¤U¾É½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-3">
    <tid>210</tid>
    <cid>3</cid>
    <description>§CÀ£¦a¤U¾É½u²Å¸¹</description>
    <elmtype>4</elmtype>
    <elmtype>12</elmtype>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-4">
    <tid>210</tid>
    <cid>4</cid>
    <description>§CÀ£¦a¤U¾É½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-211.C-0">
    <tid>211</tid>
    <cid>0</cid>
    <description>§CÀ£¬[ªÅ±µ¤á½u</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-211.C-1">
    <tid>211</tid>
    <cid>1</cid>
    <description>§CÀ£¬[ªÅ±µ¤á½u</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-211.C-2">
    <tid>211</tid>
    <cid>2</cid>
    <description>§CÀ£¬[ªÅ±µ¤á½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-212.C-0">
    <tid>212</tid>
    <cid>0</cid>
    <description>§CÀ£¬[ªÅ³s±µ±µ¤á½u</description>
    <elementCriterion>
      <elementType>4</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-212.C-1">
    <tid>212</tid>
    <cid>1</cid>
    <description>§CÀ£¬[ªÅ³s±µ±µ¤á½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-212.C-2">
    <tid>212</tid>
    <cid>2</cid>
    <description>§CÀ£¬[ªÅ³s±µ±µ¤á½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-213.C-0">
    <tid>213</tid>
    <cid>0</cid>
    <description>§CÀ£¦a¤U³s±µ±µ¤á½u</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-213.C-1">
    <tid>213</tid>
    <cid>1</cid>
    <description>§CÀ£¦a¤U³s±µ±µ¤á½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-213.C-2">
    <tid>213</tid>
    <cid>2</cid>
    <description>§CÀ£¦a¤U³s±µ±µ¤á½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-215.C-0">
    <tid>215</tid>
    <cid>0</cid>
    <description>§CÀ£¦Û°Ê­t¸ü¤Á´«¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-216.C-0">
    <tid>216</tid>
    <cid>0</cid>
    <description>¦a¤U§CÀ£ºÊµø¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-216.C-1">
    <tid>216</tid>
    <cid>1</cid>
    <description>§CÀ£ºÊµø¾¹µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-216.C-2">
    <tid>216</tid>
    <cid>2</cid>
    <description>§CÀ£ºÊµø¾¹ªùµPµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-217.C-0">
    <tid>217</tid>
    <cid>0</cid>
    <description>§CÀ£¦a¤U´å¥ð</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <!-- ¥úÆl -->
  <TypeCompFilter name="FSC-300.C-0">
    <tid>300</tid>
    <cid>0</cid>
    <description>³q°T¥úÆl½u</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-300.C-1">
    <tid>300</tid>
    <cid>1</cid>
    <description>¥úÅÖ¹qÆl«¬¦¡(ªø«×)µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-300.C-2">
    <tid>300</tid>
    <cid>2</cid>
    <description>¥úÅÖ¹qÆl¤å¦r»¡©úµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-300.C-3">
    <tid>300</tid>
    <cid>3</cid>
    <description>¥úÅÖ¹qÆl¤Þ½u²Å¸¹</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-300.C-4">
    <tid>300</tid>
    <cid>4</cid>
    <description>¥úÅÖ¹qÆl¥´ÂI²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-301.C-0">
    <tid>301</tid>
    <cid>0</cid>
    <description>¸ô¿O±±¨î½u</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-301.C-1">
    <tid>301</tid>
    <cid>1</cid>
    <description>¸ô¿O±±¨î½u¤Þ½u²Å¸¹</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-301.C-3">
    <tid>301</tid>
    <cid>3</cid>
    <description>¸ô¿O±±¨î½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-999.C-0">
    <tid>999</tid>
    <cid>0</cid>
    <description>µù°O</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-113.C-0">
    <tid>113</tid>
    <cid>0</cid>
    <description>°ªÀ£¦a¤U´å¥ð</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-0">
    <tid>403</tid>
    <cid>0</cid>
    <description>°ª§CÀ£¤H¤â¤Õ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-1">
    <tid>403</tid>
    <cid>1</cid>
    <description>°ª§CÀ£¤H¤â¤Õ®y¼Ðµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-2">
    <tid>403</tid>
    <cid>2</cid>
    <description>°ª§CÀ£¤H¤â¤Õ¶ê°é²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-4">
    <tid>403</tid>
    <cid>4</cid>
    <description>¸ô¿O¤Õ¶ê°é</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-5">
    <tid>403</tid>
    <cid>5</cid>
    <description>¸ô¿O¤Õ®y¼Ðµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-6">
    <tid>403</tid>
    <cid>6</cid>
    <description>¥úÅÖ¤Õ¶ê°é²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-7">
    <tid>403</tid>
    <cid>7</cid>
    <description>¥úÆl¤Õ®y¼Ðµù°O(¥úÆl¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-0">
    <tid>401</tid>
    <cid>0</cid>
    <description>ºÞ¸ô</description>
    <elementCriterion>
      <elementType>12</elementType>
      <elementType>16</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-1">
    <tid>401</tid>
    <cid>1</cid>
    <description>ºÞ¸ô¤Þ½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-2">
    <tid>401</tid>
    <cid>2</cid>
    <description>ºÞ¸ôºÞ´U</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-3">
    <tid>401</tid>
    <cid>3</cid>
    <description>ºÞ¸ô¤å¦r»¡©úµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-5">
    <tid>401</tid>
    <cid>5</cid>
    <description>ºÞ¸ôÂ_­±°Ï¬q°Ï¹j</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-302.C-0">
    <tid>302</tid>
    <cid>0</cid>
    <description>¸ô¿O­t¸ü½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-302.C-1">
    <tid>302</tid>
    <cid>1</cid>
    <description>¸ô¿O­t¸ü½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-303.C-0">
    <tid>303</tid>
    <cid>0</cid>
    <description>¸ô¿O¾Þ§@½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-303.C-1">
    <tid>303</tid>
    <cid>1</cid>
    <description>¸ô¿O¾Þ§@½u¤Þ½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-303.C-3">
    <tid>303</tid>
    <cid>3</cid>
    <description>¸ô¿O¾Þ§@½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-305.C-0">
    <tid>305</tid>
    <cid>0</cid>
    <description>¸ô¿OÂI·À¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-306.C-0">
    <tid>306</tid>
    <cid>0</cid>
    <description>¸ô¿O®É±±¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-307.C-0">
    <tid>307</tid>
    <cid>0</cid>
    <description>¸ô¿O¤Àª[ÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-308.C-0">
    <tid>308</tid>
    <cid>0</cid>
    <description>¸ô¿O²×ºÝ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-311.C-0">
    <tid>311</tid>
    <cid>0</cid>
    <description>¸ô¿O¥x±b</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-311.C-1">
    <tid>311</tid>
    <cid>1</cid>
    <description>¸ô¿O¥x±b¹Ï¸¹(®e¶q.·ø¼Æ)µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-314.C-0">
    <tid>314</tid>
    <cid>0</cid>
    <description>¬[ªÅ¸ô¿O­t¸ü½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-314.C-1">
    <tid>314</tid>
    <cid>1</cid>
    <description>¬[ªÅ¸ô¿O­t¸ü½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-315.C-0">
    <tid>315</tid>
    <cid>0</cid>
    <description>¬[ªÅ¸ô¿O±±¨î½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-315.C-1">
    <tid>315</tid>
    <cid>1</cid>
    <description>¬[ªÅ¸ô¿O±±¨î½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-316.C-0">
    <tid>316</tid>
    <cid>0</cid>
    <description>¸ô¿Oª½¸ô</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-317.C-0">
    <tid>317</tid>
    <cid>0</cid>
    <description>¸ô¿O±±¨î¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-317.C-1">
    <tid>317</tid>
    <cid>1</cid>
    <description>¸ô¿O±±¨î¶}Ãöµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-318.C-0">
    <tid>318</tid>
    <cid>0</cid>
    <description>¸ô¿O¶×¬y±Æ</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-319.C-0">
    <tid>319</tid>
    <cid>0</cid>
    <description>¥úÅÖ¦¬®e</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-320.C-0">
    <tid>320</tid>
    <cid>0</cid>
    <description>¥úÅÖ³q°T±µÀY</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-323.C-0">
    <tid>323</tid>
    <cid>0</cid>
    <description>¥ú¹qÂà´«¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-324.C-0">
    <tid>324</tid>
    <cid>0</cid>
    <description>¦Û°Ê¤Æ»»±±¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-324.C-1">
    <tid>324</tid>
    <cid>1</cid>
    <description>¦Û°Ê¤Æ»»±±¾¹µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <!-- Dummy
  <TypeCompLevelFilter name="DemoFeature3">
    <tid>999</tid>
    <cid>2</cid>
    <lid>34</lid>
    <description>DemoFilter for DemoFeature</description>
    <TextCreateStrategy-None/>
  </TypeCompLevelFilter>
  -->
</ElementDispatcherRules>
xdgnjobs/ximple-spatialjob/src/test/java/com/ximple/eofms/filter/ElementDispatcherTest.java
New file
@@ -0,0 +1,69 @@
package com.ximple.eofms.filter;
import java.io.File;
import java.io.IOException;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import org.geotools.TestData;
import org.testng.Assert;
import org.testng.annotations.Test;
import org.xml.sax.SAXException;
public class ElementDispatcherTest
{
    private static final String TestRulesName = "testRules.xml";
    private static final String TestConfigName = "testElementFilter.xml";
    @Test
    public void testLoadRules() throws IOException
    {
        File rules = TestData.file(this, TestRulesName);
        Digester digester = DigesterLoader.createDigester(rules.toURI().toURL());
        // File config = TestData.file(this, TestConfigName);
        // ElementDispatcher ed = (ElementDispatcher) digester.parse(config);
        Assert.assertNotNull(digester);
    }
    @Test
    public void testLoadConfig() throws IOException, SAXException
    {
        File rules = TestData.file(this, TestRulesName);
        Digester digester = DigesterLoader.createDigester(rules.toURI().toURL());
        File config = TestData.file(this, TestConfigName);
        ElementDispatcher ed = (ElementDispatcher) digester.parse(config);
        Assert.assertNotNull(ed);
       // Assert.assertEquals(ed.getRules().size(), 3);
        ElementDispatchableFilter filter = ed.getRules().get(0);
        /*
        Assert.assertTrue(filter instanceof TypeIdDispatchableFilter);
        TypeIdDispatchableFilter tFilter = (TypeIdDispatchableFilter) filter;
        Assert.assertEquals(tFilter.getName(), "DemoFeature1");
        Assert.assertEquals(tFilter.getTid(), 106);
        Assert.assertEquals(tFilter.getElmtype(), 7);
        Assert.assertNotNull(tFilter.getCreateStrategy());
        Assert.assertTrue(tFilter.getCreateStrategy() instanceof CreateLineStringStrategy);
        */
        filter = ed.getRules().get(1);
        Assert.assertTrue(filter instanceof TypeCompIdDispatchableFilter);
        TypeCompIdDispatchableFilter tcFilter = (TypeCompIdDispatchableFilter) filter;
        Assert.assertEquals(tcFilter.getName(), "DemoFeature2");
        Assert.assertEquals(tcFilter.getTid(), 107);
        Assert.assertEquals(tcFilter.getCid(), 11);
        Assert.assertNotNull(tcFilter.getCreateStrategy());
        Assert.assertTrue(tcFilter.getCreateStrategy() instanceof CreateLineTextStrategy);
        /*
        filter = ed.getRules().get(2);
        Assert.assertTrue(filter instanceof TypeCompLevelIdDispatchableFilter);
        TypeCompLevelIdDispatchableFilter tclFilter = (TypeCompLevelIdDispatchableFilter) filter;
        Assert.assertEquals(tclFilter.getName(), "DemoFeature3");
        Assert.assertEquals(tclFilter.getTid(), 108);
        Assert.assertEquals(tclFilter.getCid(), 2);
        Assert.assertEquals(tclFilter.getLid(), 34);
        Assert.assertNull(tclFilter.getCreateStrategy());
        */
    }
}
xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testElementFilter.xml
New file
@@ -0,0 +1,1406 @@
<?xml version="1.0" encoding="big5" ?>
<ElementDispatcherRules>
  <!-- High Voltage Features -->
  <TypeCompFilter name="FSC-106.C-0">
    <tid>106</tid>
    <cid>0</cid>
    <description>¥D°ªÀ£½u</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-106.C-1">
    <tid>106</tid>
    <cid>1</cid>
    <description>°ªÀ£½u¤Þ½u</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-106.C-2">
    <tid>106</tid>
    <cid>2</cid>
    <description>°ªÀ£½u¤Þ½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-106.C-4">
    <tid>106</tid>
    <cid>4</cid>
    <description>°ªÀ£½uõX½u¥N¸¹¤Þ½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-402.C-0">
    <tid>402</tid>
    <cid>0</cid>
    <description>Åܹq©Ò</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-402.C-1">
    <tid>402</tid>
    <cid>1</cid>
    <description>Åܹq©Òµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-402.C-2">
    <tid>402</tid>
    <cid>2</cid>
    <description>Åܹq©Ò¤¤¤åµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-0">
    <tid>411</tid>
    <cid>0</cid>
    <description>°t¹q³õ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-1">
    <tid>411</tid>
    <cid>1</cid>
    <description>°t¹q³õµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-2">
    <tid>411</tid>
    <cid>2</cid>
    <description>°t¹q³õ-1/600</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-3">
    <tid>411</tid>
    <cid>3</cid>
    <description>°t¹q³õµù°O-1/600</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-411.C-7">
    <tid>411</tid>
    <cid>7</cid>
    <description>°t¹q³õ1/600¤Þ¤W¤U²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-420.C-0">
    <tid>420</tid>
    <cid>0</cid>
    <description>ºÞ·¾</description>
    <elementCriterion>
      <elementType>6</elementType>
    </elementCriterion>
    <ShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-420.C-1">
    <tid>420</tid>
    <cid>1</cid>
    <description>ºÞ·¾µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-421.C-0">
    <tid>421</tid>
    <cid>0</cid>
    <description>¦@¦PºÞ¹D</description>
    <elementCriterion>
      <elementType>6</elementType>
    </elementCriterion>
    <ShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-421.C-1">
    <tid>421</tid>
    <cid>1</cid>
    <description>¦@¦PºÞ¹Dµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-423.C-0">
    <tid>423</tid>
    <cid>0</cid>
    <description>ºÞ¸ôÂ_­±</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-423.C-1">
    <tid>423</tid>
    <cid>1</cid>
    <description>ºÞ¸ôÂ_­±¤Þ½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-424.C-0">
    <tid>424</tid>
    <cid>0</cid>
    <description>¯S®í¤uªkºX¼Ð²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-501.C-0">
    <tid>501</tid>
    <cid>0</cid>
    <description>»Ùê³òÆX</description>
    <elementCriterion>
      <elementType>6</elementType>
    </elementCriterion>
    <ShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-501.C-1">
    <tid>501</tid>
    <cid>1</cid>
    <description>»Ùê³òÆX¤å¦rµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-502.C-0">
    <tid>502</tid>
    <cid>0</cid>
    <description>°ÝÃD³òÆX</description>
    <elementCriterion>
      <elementType>6</elementType>
    </elementCriterion>
    <ShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-502.C-1">
    <tid>502</tid>
    <cid>1</cid>
    <description>°ÝÃD³òÆX¤å¦rµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-503.C-0">
    <tid>503</tid>
    <cid>0</cid>
    <description>¤å¦rµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-0">
    <tid>407</tid>
    <cid>0</cid>
    <description>¹q±ì</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-1">
    <tid>407</tid>
    <cid>1</cid>
    <description>¹q±ìµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-2">
    <tid>407</tid>
    <cid>2</cid>
    <description>¹q±ì-1/600</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-3">
    <tid>407</tid>
    <cid>3</cid>
    <description>¹q±ì-1/600µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-7">
    <tid>407</tid>
    <cid>7</cid>
    <description>1/600¹q±ì¤Þ¤W¤U²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-8">
    <tid>407</tid>
    <cid>8</cid>
    <description>1/1200¹q±ì¤Þ¤W¤U²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-9">
    <tid>407</tid>
    <cid>9</cid>
    <description>¹q±ì¤ô¥­¤ä½u</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-10">
    <tid>407</tid>
    <cid>10</cid>
    <description>¹q±ì±ì¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-407.C-11">
    <tid>407</tid>
    <cid>11</cid>
    <description>¹q±ì¤ô¥­¤ä½u³»»\</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-114.C-0">
    <tid>114</tid>
    <cid>0</cid>
    <description>¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-114.C-1">
    <tid>114</tid>
    <cid>1</cid>
    <description>¶}Ãö°j¸ôµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-114.C-2">
    <tid>114</tid>
    <cid>2</cid>
    <description>¶}Ãö¤p¬P¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-114.C-3">
    <tid>114</tid>
    <cid>3</cid>
    <description>¶}Ãö¤j¬P¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-122.C-0">
    <tid>122</tid>
    <cid>0</cid>
    <description>ª½±µ³s±µ</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <LineTextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-122.C-1">
    <tid>122</tid>
    <cid>1</cid>
    <description>ª½±µ³s±µµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-107.C-0">
    <tid>107</tid>
    <cid>0</cid>
    <description>°ªÀ£¥Î¤á</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-107.C-2">
    <tid>107</tid>
    <cid>2</cid>
    <description>°ªÀ£¥Î¤á¤¤¤åµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-117.C-0">
    <tid>117</tid>
    <cid>0</cid>
    <description>TieÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-105.C-0">
    <tid>105</tid>
    <cid>0</cid>
    <description>ª½¸ô±µÀY</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-105.C-1">
    <tid>105</tid>
    <cid>1</cid>
    <description>ª½¸ô±µÀYµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-101.C-0">
    <tid>101</tid>
    <cid>0</cid>
    <description>¶×¬y±Æ</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-120.C-0">
    <tid>120</tid>
    <cid>0</cid>
    <description>¸`ÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-150.C-0">
    <tid>150</tid>
    <cid>0</cid>
    <description>¨â¸ô¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-130.C-0">
    <tid>130</tid>
    <cid>0</cid>
    <description>¾É½u¥æ¤e</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-131.C-0">
    <tid>131</tid>
    <cid>0</cid>
    <description>¾É½uÅܧó</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-109.C-0">
    <tid>109</tid>
    <cid>0</cid>
    <description>¸õ½u³s±µ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-116.C-0">
    <tid>116</tid>
    <cid>0</cid>
    <description>°ªÀ£²×ºÝ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-108.C-0">
    <tid>108</tid>
    <cid>0</cid>
    <description>Â_¸ô¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-108.C-1">
    <tid>108</tid>
    <cid>1</cid>
    <description>Â_¸ô¾¹µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-119.C-0">
    <tid>119</tid>
    <cid>0</cid>
    <description>¹qÅæ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-0">
    <tid>115</tid>
    <cid>0</cid>
    <description>ÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-1">
    <tid>115</tid>
    <cid>1</cid>
    <description>ÅÜÀ£¾¹µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-2">
    <tid>115</tid>
    <cid>2</cid>
    <description>¸ô¿O¨t²Î¹ÏÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-3">
    <tid>115</tid>
    <cid>3</cid>
    <description>¸ô¿O¨t²Î¹ÏÅÜÀ£¾¹µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-4">
    <tid>115</tid>
    <cid>4</cid>
    <description>§CÀ£¨t²Î¹ÏÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-5">
    <tid>115</tid>
    <cid>5</cid>
    <description>§CÀ£¨t²Î¹ÏÅÜÀ£¾¹µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-6">
    <tid>115</tid>
    <cid>6</cid>
    <description>§CÀ£¨t²Î¹Ï-°t¹q«Ç®y¼Ðµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-7">
    <tid>115</tid>
    <cid>7</cid>
    <description>§CÀ£¨t²Î¹Ï-°t¹q«Ç®y¼Ðµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-115.C-8">
    <tid>115</tid>
    <cid>8</cid>
    <description>¬[ªÅÅÜÀ£¾¹(¦a¤U§CÀ£¥Î)µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-118.C-0">
    <tid>118</tid>
    <cid>0</cid>
    <description>¥DÅÜÀ£¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-102.C-0">
    <tid>102</tid>
    <cid>0</cid>
    <description>¹q®e¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-100.C-0">
    <tid>100</tid>
    <cid>0</cid>
    <description>Á×¹p¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-0">
    <tid>140</tid>
    <cid>0</cid>
    <description>°ªÀ£½u¸ô(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-1">
    <tid>140</tid>
    <cid>1</cid>
    <description>¤Þ½u(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-2">
    <tid>140</tid>
    <cid>2</cid>
    <description>¾É½uµù°O(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-3">
    <tid>140</tid>
    <cid>3</cid>
    <description>õX½u¥N¸¹¤Þ½u(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-140.C-4">
    <tid>140</tid>
    <cid>4</cid>
    <description>õX½u¥N¸¹µù°O(½u¸ô¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-151.C-0">
    <tid>150</tid>
    <cid>0</cid>
    <description>±`³¬¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <!-- Low Voltage Features -->
  <TypeCompFilter name="FSC-200.C-0">
    <tid>200</tid>
    <cid>0</cid>
    <description>§CÀ£¸`ÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <!-- *****§CÀ£****** -->
  <TypeCompFilter name="FSC-201.C-0">
    <tid>201</tid>
    <cid>0</cid>
    <description>±µ¤á½u</description>
    <elementCriterion>
      <elementType>12</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-201.C-1">
    <tid>201</tid>
    <cid>1</cid>
    <description>±µ¤á½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-201.C-2">
    <tid>201</tid>
    <cid>2</cid>
    <description>±µ¤á½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-202.C-0">
    <tid>202</tid>
    <cid>0</cid>
    <description>±µ¤áÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-202.C-1">
    <tid>202</tid>
    <cid>1</cid>
    <description>±µ¤áÂIªùµPµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-203.C-0">
    <tid>203</tid>
    <cid>0</cid>
    <description>¸ô¿O³d¥ô¤À¬ÉÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-203.C-1">
    <tid>203</tid>
    <cid>1</cid>
    <description>¸ô¿O³d¥ô¤À¬ÉÂIµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-204.C-0">
    <tid>204</tid>
    <cid>0</cid>
    <description>§CÀ£¸õ½u</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-205.C-0">
    <tid>205</tid>
    <cid>0</cid>
    <description>§CÀ£¾É½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-205.C-1">
    <tid>205</tid>
    <cid>1</cid>
    <description>§CÀ£¾É½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-205.C-2">
    <tid>205</tid>
    <cid>2</cid>
    <description>§CÀ£¾É½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-206.C-0">
    <tid>206</tid>
    <cid>0</cid>
    <description>§CÀ£»»±±½c</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-207.C-0">
    <tid>207</tid>
    <cid>0</cid>
    <description>§CÀ£Äµ³ø¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-208.C-0">
    <tid>208</tid>
    <cid>0</cid>
    <description>§CÀ£²×ºÝ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-209.C-0">
    <tid>209</tid>
    <cid>0</cid>
    <description>§CÀ£¥æ³q¸¹»x</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-0">
    <tid>210</tid>
    <cid>0</cid>
    <description>§CÀ£¦a¤U¾É½u</description>
    <elmtype>12</elmtype>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-1">
    <tid>210</tid>
    <cid>1</cid>
    <description>§CÀ£¦a¤U¾É½u¥´ÂI²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-2">
    <tid>210</tid>
    <cid>2</cid>
    <description>§CÀ£¦a¤U¾É½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-3">
    <tid>210</tid>
    <cid>3</cid>
    <description>§CÀ£¦a¤U¾É½u²Å¸¹</description>
    <elmtype>4</elmtype>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-210.C-4">
    <tid>210</tid>
    <cid>4</cid>
    <description>§CÀ£¦a¤U¾É½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-211.C-0">
    <tid>211</tid>
    <cid>0</cid>
    <description>§CÀ£¬[ªÅ±µ¤á½u</description>
    <elementCriterion>
      <elementType>4</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-211.C-1">
    <tid>211</tid>
    <cid>1</cid>
    <description>§CÀ£¬[ªÅ±µ¤á½u</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-211.C-2">
    <tid>211</tid>
    <cid>2</cid>
    <description>§CÀ£¬[ªÅ±µ¤á½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-212.C-0">
    <tid>212</tid>
    <cid>0</cid>
    <description>§CÀ£¬[ªÅ³s±µ±µ¤á½u</description>
    <elementCriterion>
      <elementType>4</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-212.C-1">
    <tid>212</tid>
    <cid>1</cid>
    <description>§CÀ£¬[ªÅ³s±µ±µ¤á½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-212.C-2">
    <tid>212</tid>
    <cid>2</cid>
    <description>§CÀ£¬[ªÅ³s±µ±µ¤á½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-213.C-0">
    <tid>213</tid>
    <cid>0</cid>
    <description>§CÀ£¦a¤U³s±µ±µ¤á½u</description>
    <elementCriterion>
      <elementType>4</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-213.C-1">
    <tid>213</tid>
    <cid>1</cid>
    <description>§CÀ£¦a¤U³s±µ±µ¤á½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-213.C-2">
    <tid>213</tid>
    <cid>2</cid>
    <description>§CÀ£¦a¤U³s±µ±µ¤á½uªø«×µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-215.C-0">
    <tid>215</tid>
    <cid>0</cid>
    <description>§CÀ£¦Û°Ê­t¸ü¤Á´«¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-216.C-0">
    <tid>216</tid>
    <cid>0</cid>
    <description>¦a¤U§CÀ£ºÊµø¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-216.C-1">
    <tid>216</tid>
    <cid>1</cid>
    <description>§CÀ£ºÊµø¾¹µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-216.C-2">
    <tid>216</tid>
    <cid>2</cid>
    <description>§CÀ£ºÊµø¾¹ªùµPµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-217.C-0">
    <tid>217</tid>
    <cid>0</cid>
    <description>§CÀ£¦a¤U´å¥ð</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <!-- ¥úÆl -->
  <TypeCompFilter name="FSC-300.C-0">
    <tid>300</tid>
    <cid>0</cid>
    <description>³q°T¥úÆl½u</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-300.C-1">
    <tid>300</tid>
    <cid>1</cid>
    <description>¥úÅÖ¹qÆl«¬¦¡(ªø«×)µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-300.C-2">
    <tid>300</tid>
    <cid>2</cid>
    <description>¥úÅÖ¹qÆl¤å¦r»¡©úµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-300.C-3">
    <tid>300</tid>
    <cid>3</cid>
    <description>¥úÅÖ¹qÆl¤Þ½u²Å¸¹</description>
    <elementCriterion>
      <elementType>4</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-300.C-4">
    <tid>300</tid>
    <cid>4</cid>
    <description>¥úÅÖ¹qÆl¥´ÂI²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-301.C-0">
    <tid>301</tid>
    <cid>0</cid>
    <description>¸ô¿O±±¨î½u</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-301.C-1">
    <tid>301</tid>
    <cid>1</cid>
    <description>¸ô¿O±±¨î½u¤Þ½u²Å¸¹</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-301.C-3">
    <tid>301</tid>
    <cid>3</cid>
    <description>¸ô¿O±±¨î½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-999.C-0">
    <tid>999</tid>
    <cid>0</cid>
    <description>µù°O</description>
    <elementCriterion>
      <elementType>4</elementType>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-113.C-0">
    <tid>113</tid>
    <cid>0</cid>
    <description>°ªÀ£¦a¤U´å¥ð</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-0">
    <tid>403</tid>
    <cid>0</cid>
    <description>°ª§CÀ£¤H¤â¤Õ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-1">
    <tid>403</tid>
    <cid>1</cid>
    <description>°ª§CÀ£¤H¤â¤Õ®y¼Ðµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-2">
    <tid>403</tid>
    <cid>2</cid>
    <description>°ª§CÀ£¤H¤â¤Õ¶ê°é²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <EllipseShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-4">
    <tid>403</tid>
    <cid>4</cid>
    <description>¸ô¿O¤Õ¶ê°é</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <EllipseShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-5">
    <tid>403</tid>
    <cid>5</cid>
    <description>¸ô¿O¤Õ®y¼Ðµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-6">
    <tid>403</tid>
    <cid>6</cid>
    <description>¥úÅÖ¤Õ¶ê°é²Å¸¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <EllipseShapeCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-403.C-7">
    <tid>403</tid>
    <cid>7</cid>
    <description>¥úÆl¤Õ®y¼Ðµù°O(¥úÆl¹Ï¥Î)</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-0">
    <tid>401</tid>
    <cid>0</cid>
    <description>ºÞ¸ô</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-1">
    <tid>401</tid>
    <cid>1</cid>
    <description>ºÞ¸ô¤Þ½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-2">
    <tid>401</tid>
    <cid>2</cid>
    <description>ºÞ¸ôºÞ´U</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-3">
    <tid>401</tid>
    <cid>3</cid>
    <description>ºÞ¸ô¤å¦r»¡©úµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-401.C-5">
    <tid>401</tid>
    <cid>5</cid>
    <description>ºÞ¸ôÂ_­±°Ï¬q°Ï¹j</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-302.C-0">
    <tid>302</tid>
    <cid>0</cid>
    <description>¸ô¿O­t¸ü½u</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-302.C-1">
    <tid>302</tid>
    <cid>1</cid>
    <description>¸ô¿O­t¸ü½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-303.C-0">
    <tid>303</tid>
    <cid>0</cid>
    <description>¸ô¿O¾Þ§@½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-303.C-1">
    <tid>303</tid>
    <cid>1</cid>
    <description>¸ô¿O¾Þ§@½u¤Þ½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-303.C-3">
    <tid>303</tid>
    <cid>3</cid>
    <description>¸ô¿O¾Þ§@½uµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-305.C-0">
    <tid>305</tid>
    <cid>0</cid>
    <description>¸ô¿OÂI·À¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-306.C-0">
    <tid>306</tid>
    <cid>0</cid>
    <description>¸ô¿O®É±±¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-307.C-0">
    <tid>307</tid>
    <cid>0</cid>
    <description>¸ô¿O¤Àª[ÂI</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-308.C-0">
    <tid>308</tid>
    <cid>0</cid>
    <description>¸ô¿O²×ºÝ</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-311.C-0">
    <tid>311</tid>
    <cid>0</cid>
    <description>¸ô¿O¥x±b</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-311.C-1">
    <tid>311</tid>
    <cid>1</cid>
    <description>¸ô¿O¥x±b¹Ï¸¹(®e¶q.·ø¼Æ)µù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-314.C-0">
    <tid>314</tid>
    <cid>0</cid>
    <description>¬[ªÅ¸ô¿O­t¸ü½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-314.C-1">
    <tid>314</tid>
    <cid>1</cid>
    <description>¬[ªÅ¸ô¿O­t¸ü½uµù°O</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-315.C-0">
    <tid>315</tid>
    <cid>0</cid>
    <description>¬[ªÅ¸ô¿O±±¨î½u</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-315.C-1">
    <tid>315</tid>
    <cid>1</cid>
    <description>¬[ªÅ¸ô¿O±±¨î½u</description>
    <elementCriterion>
      <elementType>7</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-316.C-0">
    <tid>316</tid>
    <cid>0</cid>
    <description>¸ô¿Oª½¸ô</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-317.C-0">
    <tid>317</tid>
    <cid>0</cid>
    <description>¸ô¿O±±¨î¶}Ãö</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-317.C-1">
    <tid>317</tid>
    <cid>1</cid>
    <description>¸ô¿O±±¨î¶}Ãöµù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-318.C-0">
    <tid>318</tid>
    <cid>0</cid>
    <description>¸ô¿O¶×¬y±Æ</description>
    <elementCriterion>
      <elementType>12</elementType>
    </elementCriterion>
    <LineCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-319.C-0">
    <tid>319</tid>
    <cid>0</cid>
    <description>¥úÅÖ¦¬®e</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-320.C-0">
    <tid>320</tid>
    <cid>0</cid>
    <description>¥úÅÖ³q°T±µÀY</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-323.C-0">
    <tid>323</tid>
    <cid>0</cid>
    <description>¥ú¹qÂà´«¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-324.C-0">
    <tid>324</tid>
    <cid>0</cid>
    <description>¦Û°Ê¤Æ»»±±¾¹</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <SymbolCreateStrategy/>
  </TypeCompFilter>
  <TypeCompFilter name="FSC-324.C-1">
    <tid>324</tid>
    <cid>1</cid>
    <description>¦Û°Ê¤Æ»»±±¾¹µù°O</description>
    <elementCriterion>
      <elementType>17</elementType>
    </elementCriterion>
    <TextCreateStrategy/>
  </TypeCompFilter>
  <!-- Dummy
  <TypeCompLevelFilter name="DemoFeature3">
    <tid>999</tid>
    <cid>2</cid>
    <lid>34</lid>
    <description>DemoFilter for DemoFeature</description>
    <TextCreateStrategy-None/>
  </TypeCompLevelFilter>
  -->
</ElementDispatcherRules>
Diff truncated after the above file
xdgnjobs/ximple-spatialjob/src/test/resources/com/ximple/eofms/filter/test-data/testRules.xml