forked from geodmms/xdgnjobs

?? ?
2008-03-10 9299ee8ad709aaf4131af10afeeb2e43b374fba3
update for EOFM-8
1 files modified
27 files added
9564 ■■■■■ changed files
.gitattributes 27 ●●●●● patch | view | raw | blame | history
ximple-dgnio/.project 23 ●●●●● patch | view | raw | blame | history
ximple-dgnio/pom.xml 443 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ArcElement.java 166 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java 230 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexElement.java 16 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexShapeElement.java 193 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7OracleReader.java 246 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileException.java 31 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileHeader.java 58 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java 718 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java 271 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java 534 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/FrammeAttributeData.java 71 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/GeometryConverter.java 18 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/IElementHandler.java 23 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineElement.java 129 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineStringElement.java 166 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Lock.java 263 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/NIOUtilities.java 114 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ShapeElement.java 56 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/StreamLogging.java 45 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/TcbElement.java 90 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java 296 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java 291 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/UserAttributeData.java 34 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Utility.java 238 ●●●●● patch | view | raw | blame | history
ximple-dgnio/src/main/java/com/ximple/util/PrintfFormat.java 4774 ●●●●● patch | view | raw | blame | history
.gitattributes
@@ -1 +1,28 @@
* text=auto !eol
ximple-dgnio/.project svneol=native#text/xml
ximple-dgnio/pom.xml svneol=native#text/xml
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ArcElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexShapeElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7OracleReader.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileException.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileHeader.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/FrammeAttributeData.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/GeometryConverter.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/IElementHandler.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineStringElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Lock.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/NIOUtilities.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ShapeElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/StreamLogging.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/TcbElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/UserAttributeData.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Utility.java svneol=native#text/plain
ximple-dgnio/src/main/java/com/ximple/util/PrintfFormat.java svneol=native#text/plain
ximple-dgnio/.project
New file
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
    <name>ximple-dgnio</name>
    <comment></comment>
    <projects>
    </projects>
    <buildSpec>
        <buildCommand>
            <name>org.maven.ide.eclipse.maven2Builder</name>
            <arguments>
            </arguments>
        </buildCommand>
        <buildCommand>
            <name>org.eclipse.jdt.core.javabuilder</name>
            <arguments>
            </arguments>
        </buildCommand>
    </buildSpec>
    <natures>
        <nature>org.eclipse.jdt.core.javanature</nature>
        <nature>org.maven.ide.eclipse.maven2Nature</nature>
    </natures>
</projectDescription>
ximple-dgnio/pom.xml
New file
@@ -0,0 +1,443 @@
<?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>
  <groupId>com.ximple</groupId>
  <artifactId>ximple-dgnio</artifactId>
  <packaging>pom</packaging>
  <version>1.0.0-SNAPSHOT</version>
  <name>ximple-dgnio-1.0.x</name>
  <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>
  <!-- =========================================================== -->
  <!--     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>
  <dependencies>
    <dependency>
      <groupId>org.vividsolutions</groupId>
      <artifactId>jts</artifactId>
      <version>1.9</version>
    </dependency>
    <dependency>
      <groupId>com.testng</groupId>
      <artifactId>testng</artifactId>
      <classifier>jdk15</classifier>
      <version>5.7</version>
    </dependency>
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-contrib</artifactId>
      <version>3.0.1-FINAL</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.15</version>
      <!-- Same as the dependency in commons-logging -->
    </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.2</version>
          <!-- Current version is 2.3, but it cause the following exception:
                    Running org.geotools.gce.imagepyramid.ImagePyramidReaderTest
                    Error: Could not find mediaLib accelerator wrapper classes. Continuing in pure Java mode.
                    Occurs in: com.sun.media.jai.mlib.MediaLibAccessor
                    java.lang.NoClassDefFoundError: com/sun/medialib/mlib/Image
                        at com.sun.media.jai.mlib.MediaLibAccessor.setUseMlib(MediaLibAccessor.java:245)
                        at com.sun.media.jai.mlib.MlibAffineRIF.create(MlibAffineRIF.java:71)
                    -->
        </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} -Dorg.geotools.test.extensive=${extensive.tests}
            -Dorg.geotools.test.interactive=${interactive.tests} -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>
          <!-- The two following options have the opposite value of what we would
               like. They are that way because they don't seem to work as expected
               with Surefire 2.3. TODO: Try again when Surefire 2.4 will be available. -->
          <!-- 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>
  </build>
  <!-- =========================================================== -->
  <!--     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>
</project>
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ArcElement.java
New file
@@ -0,0 +1,166 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
 * ArcElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/26 ¤U¤È 06:41:45
 */
public class ArcElement extends Element implements GeometryConverter
{
    public ArcElement(short[] raw)
    {
        super(raw);
    }
    public double getPrimary()
    {
        short[] primary = new short[4];
        System.arraycopy(raw, 22, primary, 0, 4);
        return Utility.DGNToIEEEDouble(primary) / 1000.0;
    }
    public void setPrimary(double value)
    {
        double  temp    = value * 1000.0;
        short[] primary = Utility.IEEEDoubleToDGN(temp);
        System.arraycopy(primary, 0, raw, 22, 4);
    }
    public double getSecondary()
    {
        short[] secondary = new short[4];
        System.arraycopy(raw, 26, secondary, 0, 4);
        return Utility.DGNToIEEEDouble(secondary) / 1000.0;
    }
    public void setSecondary(double value)
    {
        double  temp      = value * 1000.0;
        short[] secondary = Utility.IEEEDoubleToDGN(temp);
        System.arraycopy(secondary, 0, raw, 26, 4);
    }
    public Coordinate getOrigin()
    {
        short[] x = new short[4];
        System.arraycopy(raw, 32, x, 0, 4);
        double  dx = Utility.ConverUnitToCoord((int) Utility.DGNToIEEEDouble(x));
        short[] y  = new short[4];
        System.arraycopy(raw, 36, y, 0, 4);
        double dy = Utility.ConverUnitToCoord((int) Utility.DGNToIEEEDouble(y));
        return new Coordinate(dx, dy);
    }
    public void setOrigin(Coordinate value)
    {
        double  temp = Utility.ConverCoordToUnit(value.x);
        short[] x    = Utility.IEEEDoubleToDGN(temp);
        System.arraycopy(x, 0, raw, 32, 4);
        temp = Utility.ConverCoordToUnit(value.y);
        short[] y = Utility.IEEEDoubleToDGN(temp);
        System.arraycopy(y, 0, raw, 36, 4);
    }
    public double getStartAngle()
    {
        int angle = (int) (raw[18] << 16 & 0xffff0000);
        angle += raw[19] & 0x0000ffff;
        return Utility.ConverIntToRotation(angle);
    }
    public void setStartAngle(double value)
    {
        int angle = Utility.ConverRotatioToInt(value);
        raw[18] = (short) (angle >>> 16 & 0x0000ffff);
        raw[19] = (short) (angle & 0x0000ffff);
    }
    public double getSweepAngle()
    {
        int angle = (int) (raw[20] << 16 & 0xffff0000);
        angle += raw[21] & 0x0000ffff;
        return Utility.ConverIntToRotation(angle);
    }
    public void setSweepAngle(double value)
    {
        int angle = Utility.ConverRotatioToInt(value);
        raw[20] = (short) (angle >> 16 & 0x0000ffff);
        raw[21] = (short) (angle & 0x0000ffff);
    }
    public double getRotationAngle()
    {
        int rotation = (int) (raw[30] << 16 & 0xffff0000);
        rotation += raw[31] & 0x0000ffff;
        return Utility.ConverIntToRotation(rotation);
    }
    public void setRotationAngle(double value)
    {
        int angle = Utility.ConverRotatioToInt(value);
        raw[30] = (short) (angle >> 16 & 0x0000ffff);
        raw[31] = (short) (angle & 0x0000ffff);
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        return null;    // To change body of implemented methods use File | Settings | File Templates.
    }
    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(short[] raw)
        {
            return new ArcElement(raw);
        }
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java
New file
@@ -0,0 +1,230 @@
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 com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
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
{
    ArrayList list = new ArrayList();
    public ComplexChainElement(short[] 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(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 Geometry toGeometry(GeometryFactory factory)
    {
        ArrayList list = new ArrayList();
        if (size() == 1)
        {
            Element element = (Element) get(0);
            if (element instanceof LineStringElement)
            {
                return ((LineStringElement) element).toGeometry(factory);
            } else if (element instanceof LineElement)
            {
                return ((LineElement) element).toGeometry(factory);
            } else
            {
                if (element instanceof GeometryConverter)
                {
                    return ((GeometryConverter) element).toGeometry(factory);
                }
                return null;
            }
        }
        for (ListIterator it = listIterator(); it.hasNext(); )
        {
            Element element = (Element) it.next();
            if (element instanceof LineStringElement)
            {
                list.add(((LineStringElement) element).toGeometry(factory));
            } else if (element instanceof LineElement)
            {
                list.add(((LineElement) element).toGeometry(factory));
            }
        }
        Geometry[]         ga   = (Geometry[]) list.toArray(new Geometry[list.size()]);
        GeometryCollection geos = new GeometryCollection(ga, factory);
        return geos;
    }
    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(short[] raw)
        {
            return new ComplexChainElement(raw);
        }
    }
}
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
{
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexShapeElement.java
New file
@@ -0,0 +1,193 @@
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 com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
 * ComplexShapeElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 03:45:15
 */
public class ComplexShapeElement extends Element implements ComplexElement, GeometryConverter
{
    ArrayList list = new ArrayList();
    public ComplexShapeElement(short[] 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 Geometry toGeometry(GeometryFactory factory)
    {
        ArrayList list = new ArrayList();
        for (ListIterator it = listIterator(); it.hasNext(); )
        {
            Element element = (Element) it.next();
            if (element instanceof LineStringElement)
            {
                list.add(((LineStringElement) element).toGeometry(factory));
            } else if (element instanceof LineElement)
            {
                list.add(((LineElement) element).toGeometry(factory));
            }
        }
        Geometry[]         ga   = (Geometry[]) list.toArray(new Geometry[list.size()]);
        GeometryCollection geos = new GeometryCollection(ga, factory);
        return geos;
    }
    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(short[] raw)
        {
            return new ComplexShapeElement(raw);
        }
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7OracleReader.java
New file
@@ -0,0 +1,246 @@
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 (Dgn7fileException e)
            {
                throw new RuntimeException("initialize oralce error.", e);
            }
        }
        if (_element == null)
        {
            return false;
        }
        return true;
    }
    public Element next()
    {
        Element result = _element;
        try
        {
            fetchElement();
        } catch (SQLException e)
        {
            throw new RuntimeException("Error:" + e.getMessage(), e);
        } catch (Dgn7fileException 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, Dgn7fileException
    {
        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, Dgn7fileException
    {
        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 SQLException("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 = 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 = 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)
        {
            e.printStackTrace();
            throw e;
        }
        return raw;
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileException.java
New file
@@ -0,0 +1,31 @@
package com.ximple.io.dgn7;
/**
 * Created by IntelliJ IDEA.
 * User: Ulysses
 * Date: 2007/9/13
 * Time: ¤W¤È 11:19:08
 * To change this template use File | Settings | File Templates.
 */
public class Dgn7fileException extends Exception
{
    public Dgn7fileException()
    {
    }
    public Dgn7fileException(String message)
    {
        super(message);
    }
    public Dgn7fileException(String message, Throwable cause)
    {
        super(message, cause);
    }
    public Dgn7fileException(Throwable cause)
    {
        super(cause);
    }
}
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;
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Dgn7fileReader.java
New file
@@ -0,0 +1,718 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import javax.swing.*;
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 org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
 * Dgn7fileReader
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/17 ¤U¤È 01:24:10
 */
public class Dgn7fileReader
{
    private static final Logger logger = LogManager.getLogger("com.isimple.glyphjump.io.dgn7");
    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    = Utility.ConvertFromDGN(lowCoorX);
            record.minX = Utility.ConverUnitToCoord(lowCoorX);
            int lowCoorY = buffer.getInt();
            lowCoorY    = Utility.ConvertFromDGN(lowCoorY);
            record.minY = Utility.ConverUnitToCoord(lowCoorY);
            int lowCoorZ = buffer.getInt();
            lowCoorZ    = Utility.ConvertFromDGN(lowCoorZ);
            record.minZ = Utility.ConverUnitToCoord(lowCoorZ);
            int highCoorX = buffer.getInt();
            highCoorX   = Utility.ConvertFromDGN(highCoorX);
            record.maxX = Utility.ConverUnitToCoord(highCoorX);
            int highCoorY = buffer.getInt();
            highCoorY   = Utility.ConvertFromDGN(highCoorY);
            record.maxY = Utility.ConverUnitToCoord(highCoorY);
            int highCoorZ = buffer.getInt();
            highCoorZ   = Utility.ConvertFromDGN(highCoorZ);
            record.maxZ = Utility.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;
        }
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Element.java
New file
@@ -0,0 +1,271 @@
package com.ximple.io.dgn7;
//~--- JDK imports ------------------------------------------------------------
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.List;
import com.vividsolutions.jts.geom.Envelope;
/**
 * 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;
    short[]                 raw;
    byte                    attrOffset = 0;
    public Element(short[] raw)
    {
        this.raw = raw;
    }
    public int getLineStyle()
    {
        return 0;
    }
    public Envelope getRange()
    {
        int lowCoorX = (int) ((raw[3] << 16) & 0xffff0000) + (raw[2] & 0x0000ffff);
        lowCoorX = Utility.ConvertFromDGN(lowCoorX);
        int lowCoorY = (int) ((raw[5] << 16) & 0xffff0000) + (raw[4] & 0x0000ffff);
        lowCoorY = Utility.ConvertFromDGN(lowCoorY);
        int highCoorX = (int) ((raw[9] << 16) & 0xffff0000) + (raw[8] & 0x0000ffff);
        highCoorX = Utility.ConvertFromDGN(highCoorX);
        int highCoorY = (int) ((raw[11] << 16) & 0xffff0000) + (raw[10] & 0x0000ffff);
        highCoorY = Utility.ConvertFromDGN(highCoorY);
        return new Envelope(Utility.ConverUnitToCoord(lowCoorX), Utility.ConverUnitToCoord(highCoorX),
                            Utility.ConverUnitToCoord(lowCoorY), Utility.ConverUnitToCoord(highCoorY));
    }
    public boolean isComponentElement()
    {
        if ((short) ((raw[0] >>> 7) & 0x0001) == 1)
        {
            return true;
        } else
        {
            return false;
        }
    }
    public boolean removeUserAttributeData(int iLinkageId)
    {
        return true;
    }
    public boolean removeUserAttributeData(int iLinkageId, int iLinkageIndex)
    {
        return true;
    }
    public boolean isDeleted()
    {
        if ((short) ((raw[0] >>> 15) & 0x0001) == 1)
        {
            return true;
        } else
        {
            return false;
        }
    }
    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);
        }
    }
    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 - 4];
            try
            {
                buffer.get(dst, 0, dst.length);
            } catch (BufferUnderflowException exception)
            {
                throw exception;
            }
            ByteBuffer tmpBuffer = ByteBuffer.wrap(dst);
            tmpBuffer.order(ByteOrder.LITTLE_ENDIAN);
            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(rawMem);
            return elm;
        }
        public void write(ByteBuffer buffer, Object element)
        {
        }
        public int getLength(Object element)
        {
            return ((Element) element).raw.length;
        }
        protected Element createElement(short[] raw)
        {
            return new Element(raw);
        }
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ElementType.java
New file
@@ -0,0 +1,534 @@
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()
    {
        if (id == 2)
        {
            return true;
        }
        if (id == 7)
        {
            return true;
        }
        if (id == 12)
        {
            return true;
        }
        if (id == 14)
        {
            return true;
        }
        if (id == 18)
        {
            return true;
        }
        if (id == 19)
        {
            return true;
        }
        if (id == 106)
        {
            return true;
        }
        if (id == 107)
        {
            return true;
        }
        return false;
    }
    public boolean isPointType()
    {
        if (id == 7)
        {
            return true;
        }
        if (id == 17)
        {
            return true;
        }
        return false;
    }
    public boolean isLineType()
    {
        if (id == 3)
        {
            return true;
        }
        if (id == 4)
        {
            return true;
        }
        if (id == 11)
        {
            return true;
        }
        if (id == 12)
        {
            return true;
        }
        if (id == 16)
        {
            return true;
        }
        return false;
    }
    public boolean isPolygonType()
    {
        if (id == 6)
        {
            return true;
        }
        if (id == 14)
        {
            return true;
        }
        return false;
    }
    public boolean isMultiPointType()
    {
        if (id == 3)
        {
            return true;
        }
        if (id == 4)
        {
            return true;
        }
        if (id == 6)
        {
            return true;
        }
        if (id == 11)
        {
            return true;
        }
        if (id == 12)
        {
            return true;
        }
        if (id == 13)
        {
            return true;
        }
        if (id == 14)
        {
            return true;
        }
        if (id == 15)
        {
            return true;
        }
        if (id == 16)
        {
            return true;
        }
        if (id == 22)
        {
            return true;
        }
        return false;
    }
    /**
     * 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 = new Element.ElementHandler(this);
            break;
        case 16 :
            handler = ArcElement.ElementHandler.getInstance();
            break;
        case 17 :
            handler = TextElement.ElementHandler.getInstance();
            break;
        default :
            handler = null;
        }
        return handler;
    }
}
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() + "}";
    }
}
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);
}
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);
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineElement.java
New file
@@ -0,0 +1,129 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
 * LineElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤W¤È 11:34:59
 */
public class LineElement extends Element implements GeometryConverter
{
    public LineElement(short[] raw)
    {
        super(raw);
    }
    public Coordinate getCentroid(double dTolerance)
    {
        return null;
    }
    public Coordinate getEndPoint()
    {
        int endX = (int) ((raw[22] << 16) & 0xffff0000);
        endX = endX + (raw[23] & 0x0000ffff);
        double x    = Utility.ConverUnitToCoord(endX);
        int    endY = (int) ((raw[24] << 16) & 0xffff0000);
        endY = endY + (raw[25] & 0x0000ffff);
        double y = Utility.ConverUnitToCoord(endY);
        return new Coordinate(x, y);
    }
    public Coordinate getNormal()
    {
        return null;
    }
    public Coordinate getOrigin()
    {
        return null;
    }
    public Coordinate getStartPoint()
    {
        int startX = (int) ((raw[18] << 16) & 0xffff0000);
        startX = startX + (raw[19] & 0x0000ffff);
        double x      = Utility.ConverUnitToCoord(startX);
        int    startY = (int) ((raw[20] << 16) & 0xffff0000);
        startY = startY + (raw[21] & 0x0000ffff);
        double y = Utility.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 Utility.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(short[] raw)
        {
            return new LineElement(raw);
        }
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/LineStringElement.java
New file
@@ -0,0 +1,166 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
 * LineStringElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 02:48:58
 */
public class LineStringElement extends Element implements GeometryConverter
{
    public LineStringElement(short[] 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 += Utility.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 = (int) ((raw[19 + (4 * index)] << 16) & 0xffff0000);
        x += (int) (raw[20 + (4 * index)] & 0x0000ffff);
        return Utility.ConverUnitToCoord(x);
    }
    protected void setX(int index, double dx)
    {
        int newVal = Utility.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 = (int) ((raw[21 + (4 * index)] << 16) & 0xffff0000);
        y = y + (int) (raw[22 + (4 * index)] & 0x0000ffff);
        return Utility.ConverUnitToCoord(y);
    }
    protected void setY(int index, double dy)
    {
        int newVal = Utility.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(short[] raw)
        {
            return new LineStringElement(raw);
        }
    }
}
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";
        }
    }
}
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);
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/ShapeElement.java
New file
@@ -0,0 +1,56 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
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
{
    public ShapeElement(short[] raw)
    {
        super(raw);
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        LinearRing ring = factory.createLinearRing(this.getVertices());
        return ring;
        // return factory.createPolygon(ring, 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(short[] raw)
        {
            return new ShapeElement(raw);
        }
    }
}
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);
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/TcbElement.java
New file
@@ -0,0 +1,90 @@
package com.ximple.io.dgn7;
/**
 * TcbElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 05:03:46
 */
public class TcbElement extends Element
{
    public TcbElement(short[] 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(short[] raw)
        {
            return new TcbElement(raw);
        }
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextElement.java
New file
@@ -0,0 +1,296 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
 * TextElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤W¤È 11:45:29
 */
public class TextElement extends Element implements GeometryConverter
{
    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;
//  Enter data field right justification
    public static final int TXTJUST_CB = 0;
//  Center/bottom text justification.
    public static final int TXTJUST_CC = 0;
//  Center/center text justification.
    public static final int TXTJUST_CT = 0;
//  Center/top text justification.
    public static final int TXTJUST_LB = 0;
//  Left/bottom text justification.
    public static final int TXTJUST_LC = 0;
//  Left/center text justification.
    public static final int TXTJUST_LT = 0;
//  Left/top text justification.
    public static final int TXTJUST_RB = 0;
//  Right/bottom text justification.
    public static final int TXTJUST_RC = 0;
//  Right/center text justification.
    public static final int TXTJUST_RT = 0;
    public TextElement(short[] raw)
    {
        super(raw);
    }
    public Coordinate getOrigin()
    {
        int x = (int) (raw[25] << 16 & 0xffff0000);
        x += raw[26] & 0x0000ffff;
        double dx = Utility.ConverUnitToCoord(x);
        int    y  = (int) (raw[27] << 16 & 0xffff0000);
        y += raw[28] & 0x0000ffff;
        double dy = Utility.ConverUnitToCoord(y);
        return new Coordinate(dx, dy);
    }
    public Coordinate getUserOrigin()
    {
        Coordinate origin = getOrigin();
        double     x      = origin.x;
        double     weight = getUserSetWeight();
        double     height = getUserSetHeight();
        double     angle  = Utility.ConverRotationToRadian(getRotationAngle());
        x += weight * Math.cos(angle) - height * Math.sin(angle);
        double y = origin.y;
        y += weight * Math.cos(angle) - height * Math.sin(angle);
        return new Coordinate(x, y);
    }
    private double getUserSetWeight()
    {
        int      just   = getJustification();
        Envelope range  = getRange();
        double   weight = (range.getWidth());
        switch (just)
        {
        case 0 :
        case 1 :
        case 2 :
            weight = 0;
            break;
        case 6 :
        case 7 :
        case 8 :
            weight = weight / 2;
            break;
        case 12 :
        case 13 :
        case 14 :
            break;
        }
        return weight;
    }
    private double getUserSetHeight()
    {
        int    just   = getJustification();
        double height = getTextHeight();
        switch (just)
        {
        case 2 :
        case 8 :
        case 14 :    // bottom
            height = 0;
            break;
        case 1 :
        case 7 :
        case 13 :    // center
            height = height / 2;
            break;
        case 0 :
        case 6 :
        case 12 :    // height
            break;
        }
        return height;
    }
    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 = (int) ((raw[21] << 16) & 0xffff0000);
        height += raw[22] & 0x0000ffff;
        return Utility.ConverIntToDouble(height);
    }
    public double getTextWidth()
    {
        int length = (int) (raw[19] << 16 & 0xffff0000);
        length += raw[20] & 0x0000ffff;
        return Utility.ConverIntToDouble(length);
    }
    public int getJustification()
    {
        return (int) ((raw[18] >>> 8) & 0x00000000ff);
    }
    public double getRotationAngle()
    {
        int totation = (int) ((raw[23] << 16) & 0xffff0000);
        totation += raw[24] & 0x0000ffff;
        return Utility.ConverIntToRotation(totation);
    }
    public boolean isChinese()
    {
        int isChinese = raw[30] & 0x0000ffff;
        if (isChinese == 0xfdff)
        {
            return true;
        } else
        {
            return false;
        }
    }
    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]);
            }
        }
        return val.toString();
    }
    public Geometry toGeometry(GeometryFactory factory)
    {
        return factory.createPoint(getUserOrigin());
    }
    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(short[] raw)
        {
            return new TextElement(raw);
        }
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/TextNodeElement.java
New file
@@ -0,0 +1,291 @@
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 com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
 * TextNodeElement
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 04:02:58
 */
public class TextNodeElement extends Element implements ComplexElement, GeometryConverter
{
    ArrayList list = new ArrayList();
    public TextNodeElement(short[] 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 (int) (raw[19] & 0x0000ffff);
    }
    public int getNodeNumber()
    {
        return (int) (raw[20] & 0x0000ffff);
    }
    public int getMaxLength()
    {
        return (int) (raw[21] & 0x00ff);
    }
    public int getMaxUsed()
    {
        return (int) ((raw[21] >> 8) & 0x00ff);
    }
    public int getJustification()
    {
        return (int) ((raw[22] >> 8) & 0x00ff);
    }
    public int getFontIndex()
    {
        return (int) (raw[22] & 0x00ff);
    }
    public double getLineSpacing()
    {
        int lineSpace;
        lineSpace = (int) ((raw[23] << 16) & 0xffff0000);
        lineSpace += (raw[24] & 0x0000ffff);
        return lineSpace;
    }
    public double getTextNodeLength()
    {
        int lengthMult = -1;
        lengthMult = (int) ((raw[25] << 16) & 0xffff0000);
        lengthMult += (raw[26] & 0x0000ffff);
        return Utility.ConverIntToDouble(lengthMult);
    }
    public double getTextNodeHeight()
    {
        int heightMult = -1;
        heightMult = (int) ((raw[27] << 16) & 0xffff0000);
        heightMult += (raw[28] & 0x0000ffff);
        return Utility.ConverIntToDouble(heightMult);
    }
    public double getRotationAngle()
    {
        int rotation = (int) (raw[29] << 16 & 0xffff0000);
        rotation += raw[30];
        return Utility.ConverIntToRotation(rotation);
    }
    public Coordinate getOrigin()
    {
        int x = (int) ((raw[31] << 16) & 0xffff0000);
        x += raw[32] & 0x0000ffff;
        // return Utility.ConvertFromDGN(x);
        double dx = Utility.ConverUnitToCoord(x);
        int    y  = (int) ((raw[33] << 16) & 0xffff0000);
        y += (raw[34] & 0x0000ffff);
        double dy = Utility.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(short[] raw)
        {
            return new TextNodeElement(raw);
        }
    }
}
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;
    }
}
ximple-dgnio/src/main/java/com/ximple/io/dgn7/Utility.java
New file
@@ -0,0 +1,238 @@
package com.ximple.io.dgn7;
//~--- non-JDK imports --------------------------------------------------------
import com.vividsolutions.jts.geom.Envelope;
/**
 * Utility
 *
 * @author Ulysses
 * @version 0.1
 * @since 2006/5/18 ¤U¤È 01:33:00
 */
public final class Utility
{
    public static double ConverIntToDouble(int src)
    {
        double newVal = (double) ((long) ((src * 6) / 1000.0 + 0.5)) / 1000.0;    // ?[0.5?O?¢X?F?|¡Ó????J
        return newVal;
    }
    public static int ConverDoubleToInt(double src)
    {
        int newVal = (int) (src / 6 * 1000000.0);
        return newVal;
    }
    public static int ConvertFromDGN(int aValue)
    {
        int newVal = 0;
        newVal = (((aValue ^ 0x00008000) << 16) & 0xffff0000);
        newVal += (aValue >>> 16) & 0x0000ffff;
        return newVal;
    }
    public static int ConverToDGN(int aValue)
    {
        int newVal = 0;
        newVal = (aValue << 16 & 0xffff0000);
        newVal += (((aValue ^ 0x80000000) >>> 16) & 0x0000ffff);
        return newVal;
    }
    public static double ConverIntToRotation(int aValue)
    {
        double newVal = aValue / 360000.0;
        if (newVal > 0)
        {
            newVal = (int) (newVal + 0.5);
        } else
        {
            newVal = (int) (newVal - 0.5);
        }
        return newVal;
    }
    public static int ConverRotatioToInt(double aValue)
    {
        int newVal = (int) (aValue * 360000.0);
        return newVal;
    }
    public static double ConverRotationToRadian(double aValue)
    {
        double newVal = aValue * Math.PI / 180;
        return newVal;
    }
    public static double ConverUnitToCoord(int aValue)
    {
        double newVal = 0;
        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;
        }
        Envelope newRange = new Envelope(ConverUnitToCoord((int) range.getMinX()), ConverUnitToCoord((int) range.getMaxX()),
                                         ConverUnitToCoord((int) range.getMinY()), ConverUnitToCoord((int) range.getMaxY()));
        return newRange;
    }
    public static Envelope ConverCoordToUnit(Envelope range)
    {
        if (range == null)
        {
            return null;
        }
        Envelope newRange = new Envelope(ConverCoordToUnit(range.getMinX()), ConverCoordToUnit(range.getMaxX()),
                                         ConverCoordToUnit(range.getMinY()), ConverCoordToUnit(range.getMaxY()));
        return newRange;
    }
    public static double DGNToIEEEDouble(short[] src)
    {
        int[] tmp = new int[2];
        long  des = 0;
        int   sign;
        int   exponent;
        int   rndbits;
        if (src == null)
        {
            throw new RuntimeException("Source short array is null");
        }
        tmp[0]   = (int) ((src[0] << 16) & 0xffff0000) | (src[1] & 0x0000ffff);    // ¢X?????
        tmp[1]   = (int) ((src[2] << 16) & 0xffff0000) | (src[3] & 0x0000ffff);    // ¡±C????
        sign     = (int) (tmp[0] & 0x80000000);
        exponent = (tmp[0] >>> 23) & 0x000000ff;
        if (exponent != 0)
        {
            exponent = exponent - 129 + 1023;
        }
        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;
        des    = (((long) tmp[0] << 32));
        des    = des | (long) tmp[1] & 0x00000000ffffffff;
        return Double.longBitsToDouble(des);
    }
    public static short[] IEEEDoubleToDGN(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) & 0x0ffffffff);
        tmp[1] = (int) (newVal & 0x0ffffffff);
        // sign = ( int ) ( ( uint ) tmp[ 0 ] & 0x80000000 );
        sign     = (int) 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;
        double length = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
        return length;
    }
}
ximple-dgnio/src/main/java/com/ximple/util/PrintfFormat.java
New file
Diff too large