Source Code Cross Referenced for VPFFile.java in  » GIS » GeoTools-2.4.1 » org » geotools » data » vpf » file » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.data.vpf.file 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *    GeoTools - OpenSource mapping toolkit
0003:         *    http://geotools.org
0004:         *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
0005:         *
0006:         *    This library is free software; you can redistribute it and/or
0007:         *    modify it under the terms of the GNU Lesser General Public
0008:         *    License as published by the Free Software Foundation; either
0009:         *    version 2.1 of the License, or (at your option) any later version.
0010:         *
0011:         *    This library is distributed in the hope that it will be useful,
0012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014:         *    Lesser General Public License for more details.
0015:         */
0016:        package org.geotools.data.vpf.file;
0017:
0018:        import java.io.EOFException;
0019:        import java.io.File;
0020:        import java.io.IOException;
0021:        import java.io.RandomAccessFile;
0022:        import java.net.URI;
0023:        import java.util.AbstractList;
0024:        import java.util.Iterator;
0025:        import java.util.LinkedList;
0026:        import java.util.List;
0027:        import java.util.Vector;
0028:
0029:        import org.geotools.data.vpf.VPFColumn;
0030:        import org.geotools.data.vpf.exc.VPFHeaderFormatException;
0031:        import org.geotools.data.vpf.ifc.DataTypesDefinition;
0032:        import org.geotools.data.vpf.ifc.FileConstants;
0033:        import org.geotools.data.vpf.io.TripletId;
0034:        import org.geotools.data.vpf.io.VPFInputStream;
0035:        import org.geotools.data.vpf.io.VariableIndexInputStream;
0036:        import org.geotools.data.vpf.io.VariableIndexRow;
0037:        import org.geotools.data.vpf.util.DataUtils;
0038:        import org.geotools.feature.AttributeType;
0039:        import org.geotools.feature.DefaultFeatureType;
0040:        import org.geotools.feature.Feature;
0041:        import org.geotools.feature.FeatureType;
0042:        import org.geotools.feature.GeometryAttributeType;
0043:        import org.geotools.feature.IllegalAttributeException;
0044:        import org.geotools.feature.SchemaException;
0045:        import org.geotools.feature.type.AnnotationFeatureType;
0046:        import org.geotools.filter.CompareFilter;
0047:        import org.geotools.filter.Filter;
0048:        import org.geotools.filter.LengthFunction;
0049:        import org.geotools.filter.LiteralExpression;
0050:
0051:        import com.vividsolutions.jts.geom.Coordinate;
0052:        import com.vividsolutions.jts.geom.CoordinateList;
0053:        import com.vividsolutions.jts.geom.DefaultCoordinateSequenceFactory;
0054:        import com.vividsolutions.jts.geom.GeometryFactory;
0055:
0056:        /**
0057:         * This class encapsulates VPF files. By implementing the <code>FeatureType</code> interface,
0058:         * it serves as a factory for VPFColumns. Instances of this class should
0059:         * be created by VPFFileFactory.
0060:         *
0061:         * @author <a href="mailto:jeff@ionicenterprise.com">Jeff Yutzler</a>
0062:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/vpf/src/main/java/org/geotools/data/vpf/file/VPFFile.java $
0063:         */
0064:        public class VPFFile implements  FeatureType, FileConstants,
0065:                DataTypesDefinition {
0066:            //    private final TableInputStream stream;
0067:            private static String ACCESS_MODE = "r";
0068:
0069:            /**
0070:             * Variable <code>byteOrder</code> keeps value of  byte order in which
0071:             * table is written:
0072:             * 
0073:             * <ul>
0074:             * <li>
0075:             * <b>L</b> - least-significant-first
0076:             * </li>
0077:             * <li>
0078:             * <b>M</b> - most-significant-first
0079:             * </li>
0080:             * </ul>
0081:             */
0082:            private char byteOrder = LEAST_SIGNIF_FIRST;
0083:            /**
0084:             * The columns of the file. This list shall contain objects of type <code>VPFColumn</code>
0085:             */
0086:            private final List columns = new Vector();
0087:
0088:            /**
0089:             * Variable <code>description</code> keeps value of text description of the
0090:             * table's contents.
0091:             */
0092:            private String description = null;
0093:            /**
0094:             * The contained Feature Type
0095:             */
0096:            private final FeatureType featureType;
0097:
0098:            /**
0099:             * Keeps value of length of ASCII header
0100:             * string (i.e., the remaining information after this field)
0101:             */
0102:            private int headerLength = -0;
0103:
0104:            /** The associated stream */
0105:            private RandomAccessFile inputStream = null;
0106:
0107:            /**
0108:             * Variable <code>narrativeTable</code> keeps value of  an optional
0109:             * narrative file which contains miscellaneous information about the
0110:             * table.
0111:             */
0112:            private String narrativeTable = null;
0113:
0114:            /** The path name */
0115:            private final String pathName;
0116:
0117:            /** Describe variable <code>variableIndex</code> here. */
0118:            private VPFInputStream variableIndex = null;
0119:
0120:            /**
0121:             * Constructor.
0122:             *
0123:             * @param cPathName The path to this file
0124:             *
0125:             * @throws IOException if the path or the file are invalid
0126:             * @throws SchemaException if the contained feature type can not be
0127:             *         constructed
0128:             */
0129:            public VPFFile(String cPathName) throws IOException,
0130:                    SchemaException {
0131:                pathName = cPathName;
0132:                inputStream = new RandomAccessFile(cPathName, ACCESS_MODE);
0133:                readHeader();
0134:
0135:                GeometryAttributeType gat = null;
0136:                VPFColumn geometryColumn = null;
0137:
0138:                Iterator iter = columns.iterator();
0139:                while (iter.hasNext()) {
0140:                    geometryColumn = (VPFColumn) iter.next();
0141:
0142:                    if (geometryColumn.isGeometry()) {
0143:                        gat = geometryColumn.getGeometryAttributeType();
0144:
0145:                        break;
0146:                    }
0147:                }
0148:
0149:                Vector super Types = new Vector();
0150:                // if it's a text geometry feature type add annotation as a super type
0151:                if (pathName.endsWith(TEXT_PRIMITIVE)) {
0152:                    super Types.add(AnnotationFeatureType.ANNOTATION);
0153:                }
0154:
0155:                featureType = new DefaultFeatureType(cPathName, "VPF", columns,
0156:                        super Types, gat);
0157:            }
0158:
0159:            /**
0160:             * Create a new feature from the provided attributes It is unclear why one
0161:             * would want to use this method.
0162:             *
0163:             * @param attributes the attributes to used
0164:             *
0165:             * @return the created feature
0166:             *
0167:             * @throws IllegalAttributeException if any of the attributes is invalid
0168:             */
0169:            public Feature create(Object[] attributes)
0170:                    throws IllegalAttributeException {
0171:                return featureType.create(attributes);
0172:            }
0173:
0174:            /*
0175:             *  (non-Javadoc)
0176:             * @see org.geotools.feature.FeatureFactory#create(java.lang.Object[], java.lang.String)
0177:             */
0178:            public Feature create(Object[] attributes, String featureID)
0179:                    throws IllegalAttributeException {
0180:                return featureType.create(attributes, featureID);
0181:            }
0182:
0183:            /*
0184:             *  (non-Javadoc)
0185:             * @see org.geotools.feature.FeatureType#duplicate(org.geotools.feature.Feature)
0186:             */
0187:            public Feature duplicate(Feature feature)
0188:                    throws IllegalAttributeException {
0189:                return featureType.duplicate(feature);
0190:            }
0191:
0192:            /*
0193:             *  (non-Javadoc)
0194:             * @see org.geotools.feature.FeatureType#find(org.geotools.feature.AttributeType)
0195:             */
0196:            public int find(AttributeType type) {
0197:                return featureType.find(type);
0198:            }
0199:
0200:            /**
0201:             * Gets the value of full length of ASCII header string including
0202:             * <code>headerLength</code> field.
0203:             *
0204:             * @return the value of headerLength
0205:             */
0206:            private int getAdjustedHeaderLength() {
0207:                return this .headerLength + 4;
0208:            }
0209:
0210:            /*
0211:             *  (non-Javadoc)
0212:             * @see org.geotools.feature.FeatureType#getAncestors()
0213:             */
0214:            public FeatureType[] getAncestors() {
0215:                return featureType.getAncestors();
0216:            }
0217:
0218:            /*
0219:             *  (non-Javadoc)
0220:             * @see org.geotools.feature.FeatureType#getAttributeCount()
0221:             */
0222:            public int getAttributeCount() {
0223:                return featureType.getAttributeCount();
0224:            }
0225:
0226:            /*
0227:             *  (non-Javadoc)
0228:             * @see org.geotools.feature.FeatureType#getAttributeType(int)
0229:             */
0230:            public AttributeType getAttributeType(int position) {
0231:                return featureType.getAttributeType(position);
0232:            }
0233:
0234:            /*
0235:             *  (non-Javadoc)
0236:             * @see org.geotools.feature.FeatureType#getAttributeType(java.lang.String)
0237:             */
0238:            public AttributeType getAttributeType(String xPath) {
0239:                return featureType.getAttributeType(xPath);
0240:            }
0241:
0242:            /*
0243:             *  (non-Javadoc)
0244:             * @see org.geotools.feature.FeatureType#getAttributeTypes()
0245:             */
0246:            public AttributeType[] getAttributeTypes() {
0247:                return featureType.getAttributeTypes();
0248:            }
0249:
0250:            /**
0251:             * Gets the value of byteOrder variable. Byte order in which table is
0252:             * written:
0253:             * 
0254:             * <ul>
0255:             * <li>
0256:             * <b>L</b> - least-significant-first
0257:             * </li>
0258:             * <li>
0259:             * <b>M</b> - most-significant-first
0260:             * </li>
0261:             * </ul>
0262:             * 
0263:             *
0264:             * @return the value of byteOrder
0265:             */
0266:            public char getByteOrder() {
0267:                return byteOrder;
0268:            }
0269:
0270:            /*
0271:             *  (non-Javadoc)
0272:             * @see org.geotools.feature.FeatureType#getDefaultGeometry()
0273:             */
0274:            public GeometryAttributeType getDefaultGeometry() {
0275:                return featureType.getDefaultGeometry();
0276:            }
0277:
0278:            /**
0279:             * Gets the value of the description of table content. This is nice to
0280:             * have, but I don't know how to make use of it.
0281:             *
0282:             * @return the value of description
0283:             */
0284:            public String getDescription() {
0285:                return description;
0286:            }
0287:
0288:            /**
0289:             * Returns the directory name for this file by chopping off the file name
0290:             * and the separator.
0291:             *
0292:             * @return the directory name for this file
0293:             */
0294:            public String getDirectoryName() {
0295:                String result = new String();
0296:                int index = pathName.lastIndexOf(File.separator);
0297:
0298:                if (index >= 0) {
0299:                    result = pathName.substring(0, index);
0300:                }
0301:
0302:                return result;
0303:            }
0304:
0305:            /**
0306:             * Returns the file name (without path) for the file
0307:             *
0308:             * @return the file name for this file
0309:             */
0310:            public String getFileName() {
0311:                String result = pathName.substring(pathName
0312:                        .lastIndexOf(File.separator) + 1);
0313:
0314:                return result;
0315:            }
0316:
0317:            /*
0318:             *  (non-Javadoc)
0319:             * @see org.geotools.feature.FeatureType#getNamespace()
0320:             */
0321:            public URI getNamespace() {
0322:                return featureType.getNamespace();
0323:            }
0324:
0325:            //    /*
0326:            //     *  (non-Javadoc)
0327:            //     * @see org.geotools.feature.FeatureType#getNamespace()
0328:            //     */
0329:            //    public URI getNamespaceURI() {
0330:            //        return featureType.getNamespaceURI();
0331:            //    }
0332:
0333:            /**
0334:             * Gets the value of narrativeTable variable file name.
0335:             *
0336:             * @return the value of narrativeTable
0337:             */
0338:            public String getNarrativeTable() {
0339:                return narrativeTable;
0340:            }
0341:
0342:            /**
0343:             * Gets the full path name for this file
0344:             *
0345:             * @return the path name for this file
0346:             */
0347:            public String getPathName() {
0348:                return pathName;
0349:            }
0350:
0351:            /**
0352:             * Method <code><code>getRecordSize</code></code> is used to return size in
0353:             * bytes of records stored in this table. If table keeps variable length
0354:             * records <code>-1</code> should be returned.
0355:             *
0356:             * @return an <code><code>int</code></code> value
0357:             */
0358:            protected int getRecordSize() {
0359:                int size = 0;
0360:                //        int currentSize;
0361:
0362:                Iterator iter = columns.iterator();
0363:
0364:                while (iter.hasNext()) {
0365:                    VPFColumn column = (VPFColumn) iter.next();
0366:                    //            currentSize = column.getFieldLength();
0367:                    if (column.getRestriction() == Filter.INCLUDE
0368:                            || column.getRestriction() == null) {
0369:                        //            if (currentSize < 0) {
0370:                        return -1;
0371:                    } else {
0372:                        int currentSize = 0;
0373:                        if (column.getRestriction() instanceof  CompareFilter) {
0374:                            try {
0375:                                CompareFilter cf = (CompareFilter) column
0376:                                        .getRestriction();
0377:                                if (cf.getLeftValue() instanceof  LengthFunction) {
0378:                                    currentSize = Integer
0379:                                            .parseInt(((LiteralExpression) cf
0380:                                                    .getRightValue())
0381:                                                    .getLiteral().toString());
0382:                                } else {
0383:                                    if (cf.getRightValue() instanceof  LengthFunction)
0384:                                        currentSize = Integer
0385:                                                .parseInt(((LiteralExpression) cf
0386:                                                        .getLeftValue())
0387:                                                        .getLiteral()
0388:                                                        .toString());
0389:                                }
0390:                            } catch (Throwable t) {
0391:                            }
0392:                        }
0393:                        size += currentSize;
0394:                    }
0395:                }
0396:
0397:                return size;
0398:            }
0399:
0400:            /**
0401:             * Returns a row with a matching value for the provided column
0402:             *
0403:             * @param idName The name of the column to look for, such as "id"
0404:             * @param id An identifier for the requested row
0405:             *
0406:             * @return The first row which matches the ID
0407:             *
0408:             * @throws IllegalAttributeException The feature can not be created due to
0409:             *         illegal attributes in the source file
0410:             */
0411:            public Feature getRowFromId(String idName, int id)
0412:                    throws IllegalAttributeException {
0413:                Feature result = null;
0414:
0415:                try {
0416:                    // This speeds things up mightily
0417:                    String firstColumnName = ((VPFColumn) columns.get(0))
0418:                            .getName();
0419:
0420:                    if (idName.equals(firstColumnName)) {
0421:                        setPosition(id);
0422:                        result = readFeature();
0423:
0424:                        Number value = (Number) result.getAttribute(idName);
0425:
0426:                        // Check to make sure we got a primary key match
0427:                        if ((value == null) || (value.intValue() != id)) {
0428:                            result = null;
0429:                        }
0430:                    }
0431:
0432:                    if (result == null) {
0433:                        Iterator joinedIter = readAllRows().iterator();
0434:                        result = getRowFromIterator(joinedIter, idName, id);
0435:                    }
0436:                } catch (IOException exc) {
0437:                    exc.printStackTrace();
0438:                }
0439:
0440:                return result;
0441:            }
0442:
0443:            /**
0444:             * Returns a single matching row from the Iterator,  ignoring rows that do
0445:             * not match a particular id
0446:             *
0447:             * @param iter the iterator to examine
0448:             * @param idName The name of the column to check
0449:             * @param id The value of the column to check
0450:             *
0451:             * @return a TableRow that matches the other parameters
0452:             */
0453:            private Feature getRowFromIterator(Iterator iter, String idName,
0454:                    int id) {
0455:                Feature result = null;
0456:                Feature currentFeature;
0457:                int value = -1;
0458:
0459:                while (iter.hasNext()) {
0460:                    currentFeature = (Feature) iter.next();
0461:                    try {
0462:                        value = Integer.parseInt(currentFeature.getAttribute(
0463:                                idName).toString());
0464:
0465:                        if (id == value) {
0466:                            result = currentFeature;
0467:
0468:                            break;
0469:                        }
0470:                    } catch (NumberFormatException exc) {
0471:                        // If this happens, the data is invalid so dumping a stack trace seems reasonable
0472:                        exc.printStackTrace();
0473:                    }
0474:                }
0475:
0476:                return result;
0477:            }
0478:
0479:            /*
0480:             *  (non-Javadoc)
0481:             * @see org.geotools.feature.FeatureType#getTypeName()
0482:             */
0483:            public String getTypeName() {
0484:                return featureType.getTypeName();
0485:            }
0486:
0487:            /*
0488:             *  (non-Javadoc)
0489:             * @see org.geotools.feature.FeatureType#hasAttributeType(java.lang.String)
0490:             */
0491:            public boolean hasAttributeType(String xPath) {
0492:                return featureType.hasAttributeType(xPath);
0493:            }
0494:
0495:            /**
0496:             * Determines if the stream contains storage for another object. Who knows
0497:             * how well this will work on variable length objects?
0498:             *
0499:             * @return a <code>boolean</code> 
0500:             */
0501:            public boolean hasNext() {
0502:                boolean result = false;
0503:
0504:                try {
0505:                    int recordSize = getRecordSize();
0506:
0507:                    if (recordSize > 0) {
0508:                        result = inputStream.length() >= (inputStream
0509:                                .getFilePointer() + recordSize);
0510:                    } else {
0511:                        result = inputStream.length() >= (inputStream
0512:                                .getFilePointer() + 1);
0513:                    }
0514:                } catch (IOException exc) {
0515:                    // No idea what to do if this happens
0516:                    exc.printStackTrace();
0517:                }
0518:
0519:                return result;
0520:            }
0521:
0522:            /*
0523:             *  (non-Javadoc)
0524:             * @see org.geotools.feature.FeatureType#isAbstract()
0525:             */
0526:            public boolean isAbstract() {
0527:                return featureType.isAbstract();
0528:            }
0529:
0530:            /*
0531:             *  (non-Javadoc)
0532:             * @see org.geotools.feature.FeatureType#isDescendedFrom(org.geotools.feature.FeatureType)
0533:             */
0534:            public boolean isDescendedFrom(FeatureType type) {
0535:                return featureType.isDescendedFrom(type);
0536:            }
0537:
0538:            /*
0539:             *  (non-Javadoc)
0540:             * @see org.geotools.feature.FeatureType#isDescendedFrom(java.lang.String, java.lang.String)
0541:             */
0542:            public boolean isDescendedFrom(URI nsURI, String typeName) {
0543:                return featureType.isDescendedFrom(nsURI, typeName);
0544:            }
0545:
0546:            /**
0547:             * Generates a list containing all of the features in the file
0548:             *
0549:             * @return a <code>List</code> value containing Feature objects
0550:             *
0551:             * @exception IOException if an error occurs
0552:             */
0553:            public AbstractList readAllRows() throws IOException {
0554:                AbstractList list = new LinkedList();
0555:
0556:                try {
0557:                    setPosition(1);
0558:                } catch (IOException exc) {
0559:                    // This indicates that there are no rows
0560:                    return list;
0561:                }
0562:
0563:                try {
0564:                    Feature row = readFeature();
0565:
0566:                    while (row != null) {
0567:                        list.add(row);
0568:                        if (hasNext()) {
0569:                            row = readFeature();
0570:                        } else {
0571:                            row = null;
0572:                        }
0573:                    }
0574:                } catch (IllegalAttributeException exc1) {
0575:                    throw new IOException(exc1.getMessage());
0576:                }
0577:
0578:                return list;
0579:            }
0580:
0581:            /**
0582:             * Reads a single byte as a character value
0583:             *
0584:             * @return a <code>char</code> value
0585:             *
0586:             * @exception IOException if an error occurs
0587:             */
0588:            protected char readChar() throws IOException {
0589:                return (char) inputStream.read();
0590:            }
0591:
0592:            /**
0593:             * Reads a column definition from the file header
0594:             *
0595:             * @return a <code>VPFColumn</code> value
0596:             *
0597:             * @exception VPFHeaderFormatException if an error occurs
0598:             * @exception IOException if an error occurs
0599:             * @exception NumberFormatException if an error occurs
0600:             */
0601:            private VPFColumn readColumn() throws VPFHeaderFormatException,
0602:                    IOException, NumberFormatException {
0603:                char ctrl = readChar();
0604:
0605:                if (ctrl == VPF_RECORD_SEPARATOR) {
0606:                    return null;
0607:                }
0608:
0609:                String name = ctrl + readString("=");
0610:                char type = readChar();
0611:                ctrl = readChar();
0612:
0613:                if (ctrl != VPF_ELEMENT_SEPARATOR) {
0614:                    throw new VPFHeaderFormatException(
0615:                            "Header format does not fit VPF file definition.");
0616:                }
0617:
0618:                String elemStr = readString(
0619:                        new String() + VPF_ELEMENT_SEPARATOR).trim();
0620:
0621:                if (elemStr.equals("*")) {
0622:                    elemStr = "-1";
0623:                }
0624:
0625:                int elements = Integer.parseInt(elemStr);
0626:                char key = readChar();
0627:                ctrl = readChar();
0628:
0629:                if (ctrl != VPF_ELEMENT_SEPARATOR) {
0630:                    throw new VPFHeaderFormatException(
0631:                            "Header format does not fit VPF file definition.");
0632:                }
0633:
0634:                String colDesc = readString(new String()
0635:                        + VPF_ELEMENT_SEPARATOR + VPF_FIELD_SEPARATOR);
0636:                String descTableName = readString(new String()
0637:                        + VPF_ELEMENT_SEPARATOR + VPF_FIELD_SEPARATOR);
0638:                String indexFile = readString(new String()
0639:                        + VPF_ELEMENT_SEPARATOR + VPF_FIELD_SEPARATOR);
0640:                String narrTable = readString(new String()
0641:                        + VPF_ELEMENT_SEPARATOR + VPF_FIELD_SEPARATOR);
0642:
0643:                return new VPFColumn(name, type, elements, key, colDesc,
0644:                        descTableName, indexFile, narrTable);
0645:            }
0646:
0647:            /**
0648:             * Constructs an object which is an instance of Geometry 
0649:             * by reading values from the file.
0650:             * @param instancesCount number of coordinates to read
0651:             * @param dimensionality either 2 or 3
0652:             * @param readDoubles true: read a double value; false: read a float value
0653:             * @return the constructed object
0654:             * @throws IOException on any file IO errors
0655:             */
0656:            protected Object readGeometry(int instancesCount,
0657:                    int dimensionality, boolean readDoubles) throws IOException {
0658:                Object result = null;
0659:                Coordinate coordinate = null;
0660:                CoordinateList coordinates = new CoordinateList();
0661:                GeometryFactory factory = new GeometryFactory();
0662:
0663:                for (int inx = 0; inx < instancesCount; inx++) {
0664:                    switch (dimensionality) {
0665:                    case 2:
0666:                        coordinate = new Coordinate(readDoubles ? readDouble()
0667:                                : readFloat(), readDoubles ? readDouble()
0668:                                : readFloat());
0669:
0670:                        break;
0671:
0672:                    case 3:
0673:                        coordinate = new Coordinate(readDoubles ? readDouble()
0674:                                : readFloat(), readDoubles ? readDouble()
0675:                                : readFloat(), readDoubles ? readDouble()
0676:                                : readFloat());
0677:
0678:                        break;
0679:
0680:                    default:
0681:                        //WTF???
0682:                    }
0683:
0684:                    coordinates.add(coordinate);
0685:                }
0686:
0687:                // Special handling for text primitives per the VPF spec.
0688:                // The first 2 points are the endpoints of the line, the following
0689:                // points fill in between the first 2 points.  
0690:                if (pathName.endsWith(TEXT_PRIMITIVE) && coordinates.size() > 2) {
0691:                    Object o = coordinates.remove(1);
0692:                    coordinates.add(o);
0693:                }
0694:
0695:                if (instancesCount == 1) {
0696:                    result = factory.createPoint(coordinate);
0697:                } else {
0698:                    result = factory
0699:                            .createLineString(DefaultCoordinateSequenceFactory
0700:                                    .instance().create(
0701:                                            coordinates.toCoordinateArray()));
0702:                }
0703:
0704:                return result;
0705:            }
0706:
0707:            /**
0708:             * Retrieves a double from the file
0709:             *
0710:             * @return a <code>double</code> value
0711:             *
0712:             * @exception IOException if an error occurs
0713:             */
0714:            protected double readDouble() throws IOException {
0715:                return DataUtils.decodeDouble(readNumber(DATA_LONG_FLOAT_LEN));
0716:            }
0717:
0718:            /**
0719:             * Retrieves a feature from the file
0720:             *
0721:             * @return the retieved feature
0722:             *
0723:             * @throws IOException on any file IO errors
0724:             * @throws IllegalAttributeException if any of the attributes retrieved are
0725:             *         illegal
0726:             */
0727:            public Feature readFeature() throws IOException,
0728:                    IllegalAttributeException {
0729:                Feature result = null;
0730:                Iterator iter = columns.iterator();
0731:                VPFColumn column;
0732:                boolean textPrimitive = pathName.endsWith(TEXT_PRIMITIVE);
0733:                int size = columns.size();
0734:                if (textPrimitive)
0735:                    size++;
0736:                Object[] values = new Object[size];
0737:
0738:                try {
0739:                    for (int inx = 0; inx < columns.size(); inx++) {
0740:                        column = (VPFColumn) columns.get(inx);
0741:
0742:                        if (column.getRestriction() == Filter.INCLUDE
0743:                                || column.getRestriction() == null) {
0744:                            //                    if (column.getFieldLength() < 0) {
0745:                            values[inx] = readVariableSizeData(column
0746:                                    .getTypeChar());
0747:                        } else {
0748:                            values[inx] = readFixedSizeData(column
0749:                                    .getTypeChar(), column.getElementsNumber());
0750:                        }
0751:                    }
0752:                    if (textPrimitive) {
0753:                        values[size - 1] = "nam";
0754:                    }
0755:
0756:                    result = featureType.create(values);
0757:                } catch (EOFException exp) {
0758:                    // Should we be throwing an exception instead of eating it?
0759:                    exp.printStackTrace();
0760:                }
0761:
0762:                return result;
0763:            }
0764:
0765:            /**
0766:             * Retrieves a fixed amount of data from the file
0767:             *
0768:             * @param dataType a <code>char</code> value indicating the data type
0769:             * @param instancesCount an <code>int</code> value indicating the number 
0770:             * of instances to retrieve.
0771:             *
0772:             * @return an <code>Object</code> value
0773:             *
0774:             * @exception IOException if an error occurs
0775:             */
0776:            protected Object readFixedSizeData(char dataType, int instancesCount)
0777:                    throws IOException {
0778:                Object result = null;
0779:
0780:                switch (dataType) {
0781:                case DATA_TEXT:
0782:                case DATA_LEVEL1_TEXT:
0783:                case DATA_LEVEL2_TEXT:
0784:                case DATA_LEVEL3_TEXT:
0785:
0786:                    byte[] dataBytes = new byte[instancesCount
0787:                            * DataUtils.getDataTypeSize(dataType)];
0788:                    inputStream.readFully(dataBytes);
0789:                    result = DataUtils.decodeData(dataBytes, dataType);
0790:
0791:                    break;
0792:
0793:                case DATA_SHORT_FLOAT:
0794:                    result = new Float(readFloat());
0795:
0796:                    break;
0797:
0798:                case DATA_LONG_FLOAT:
0799:                    result = new Double(readDouble());
0800:
0801:                    break;
0802:
0803:                case DATA_SHORT_INTEGER:
0804:                    result = new Short(readShort());
0805:
0806:                    break;
0807:
0808:                case DATA_LONG_INTEGER:
0809:                    result = new Integer(readInteger());
0810:
0811:                    break;
0812:
0813:                case DATA_NULL_FIELD:
0814:                    result = "NULL";
0815:
0816:                    break;
0817:
0818:                case DATA_TRIPLET_ID:
0819:                    result = readTripletId();
0820:
0821:                    break;
0822:
0823:                case DATA_2_COORD_F:
0824:                    result = readGeometry(instancesCount, 2, false);
0825:
0826:                    break;
0827:
0828:                case DATA_2_COORD_R:
0829:                    result = readGeometry(instancesCount, 2, true);
0830:
0831:                    break;
0832:
0833:                case DATA_3_COORD_F:
0834:                    result = readGeometry(instancesCount, 3, false);
0835:
0836:                    break;
0837:
0838:                case DATA_3_COORD_R:
0839:                    result = readGeometry(instancesCount, 3, true);
0840:
0841:                    break;
0842:
0843:                default:
0844:                    break;
0845:                } // end of switch (dataType)
0846:
0847:                return result;
0848:            }
0849:
0850:            /**
0851:             * Retrieves a floating point number from the file.
0852:             *
0853:             * @return a <code>float</code> value
0854:             *
0855:             * @exception IOException if an error occurs
0856:             */
0857:            protected float readFloat() throws IOException {
0858:                return DataUtils.decodeFloat(readNumber(DATA_SHORT_FLOAT_LEN));
0859:            }
0860:
0861:            /**
0862:             * Retrieves a number of attributes from the file header
0863:             *
0864:             * @exception VPFHeaderFormatException if an error occurs
0865:             * @exception IOException if an error occurs
0866:             */
0867:            protected void readHeader() throws VPFHeaderFormatException,
0868:                    IOException {
0869:                byte[] fourBytes = new byte[4];
0870:                inputStream.readFully(fourBytes);
0871:
0872:                byteOrder = readChar();
0873:
0874:                char ctrl = byteOrder;
0875:
0876:                if (byteOrder == VPF_RECORD_SEPARATOR) {
0877:                    byteOrder = LITTLE_ENDIAN_ORDER;
0878:                } else {
0879:                    ctrl = readChar();
0880:                }
0881:
0882:                if (byteOrder == LITTLE_ENDIAN_ORDER) {
0883:                    fourBytes = DataUtils.toBigEndian(fourBytes);
0884:                }
0885:
0886:                headerLength = DataUtils.decodeInt(fourBytes);
0887:
0888:                if (ctrl != VPF_RECORD_SEPARATOR) {
0889:                    throw new VPFHeaderFormatException(
0890:                            "Header format does not fit VPF file definition.");
0891:                }
0892:
0893:                description = readString(new String() + VPF_RECORD_SEPARATOR);
0894:                narrativeTable = readString(new String() + VPF_RECORD_SEPARATOR);
0895:
0896:                VPFColumn column = readColumn();
0897:
0898:                while (column != null) {
0899:                    columns.add(column);
0900:                    ctrl = readChar();
0901:
0902:                    if (ctrl != VPF_FIELD_SEPARATOR) {
0903:                        throw new VPFHeaderFormatException(
0904:                                "Header format does not fit VPF file definition.");
0905:                    }
0906:
0907:                    column = readColumn();
0908:                }
0909:
0910:                if (getRecordSize() < 0) {
0911:                    variableIndex = new VariableIndexInputStream(
0912:                            getVariableIndexFileName(), getByteOrder());
0913:                }
0914:            }
0915:
0916:            /**
0917:             * Retrieves an integer value from the file
0918:             *
0919:             * @return an <code>int</code> value
0920:             *
0921:             * @exception IOException if an error occurs
0922:             */
0923:            protected int readInteger() throws IOException {
0924:                return DataUtils.decodeInt(readNumber(DATA_LONG_INTEGER_LEN));
0925:            }
0926:
0927:            /**
0928:             * Reads some byte data from the file
0929:             *
0930:             * @param cnt an <code>int</code> value indicating the number of bytes to retrieve
0931:             *
0932:             * @return a <code>byte[]</code> value
0933:             *
0934:             * @throws IOException if an error occurs
0935:             */
0936:            protected byte[] readNumber(int cnt) throws IOException {
0937:                byte[] dataBytes = new byte[cnt];
0938:                inputStream.readFully(dataBytes);
0939:
0940:                if (byteOrder == LITTLE_ENDIAN_ORDER) {
0941:                    dataBytes = DataUtils.toBigEndian(dataBytes);
0942:                }
0943:
0944:                return dataBytes;
0945:            }
0946:
0947:            /**
0948:             * Retrieves a short value from the file
0949:             *
0950:             * @return a <code>short</code> value
0951:             *
0952:             * @exception IOException if an error occurs
0953:             */
0954:            protected short readShort() throws IOException {
0955:                return DataUtils
0956:                        .decodeShort(readNumber(DATA_SHORT_INTEGER_LEN));
0957:            }
0958:
0959:            /**
0960:             * Reads a string value from the file
0961:             *
0962:             * @param terminators a <code>String</code> value indicating the terminators to look for
0963:             *
0964:             * @return a <code>String</code> value
0965:             *
0966:             * @exception IOException if an error occurs
0967:             */
0968:            protected String readString(String terminators) throws IOException {
0969:                StringBuffer text = new StringBuffer();
0970:                char ctrl = readChar();
0971:
0972:                if (terminators.indexOf(ctrl) != -1) {
0973:                    if (ctrl == VPF_FIELD_SEPARATOR) {
0974:                        unread(1);
0975:                    }
0976:
0977:                    return null;
0978:                }
0979:
0980:                while (terminators.indexOf(ctrl) == -1) {
0981:                    text.append(ctrl);
0982:                    ctrl = readChar();
0983:                }
0984:
0985:                if (text.toString().equals(STRING_NULL_VALUE)) {
0986:                    return null;
0987:                } else {
0988:                    return text.toString();
0989:                }
0990:            }
0991:
0992:            /**
0993:             * Retrieves a triplet object from the file
0994:             *
0995:             * @return a <code>TripletId</code> value
0996:             * 
0997:             * @throws IOException on any IO errors
0998:             */
0999:            protected TripletId readTripletId() throws IOException {
1000:                // TODO: does this take into account byte order properly?
1001:                byte tripletDef = (byte) inputStream.read();
1002:                int dataSize = TripletId.calculateDataSize(tripletDef);
1003:                byte[] tripletData = new byte[dataSize + 1];
1004:                tripletData[0] = tripletDef;
1005:
1006:                if (dataSize > 0) {
1007:                    inputStream.readFully(tripletData, 1, dataSize);
1008:                }
1009:
1010:                return new TripletId(tripletData);
1011:            }
1012:
1013:            /**
1014:             * Retrieves variable sized data from the file by first reading an integer
1015:             * which indicates how many instances of the data type to retrieve
1016:             *
1017:             * @param dataType a <code>char</code> value indicating the data type
1018:             *
1019:             * @return an <code>Object</code> value
1020:             *
1021:             * @exception IOException if an error occurs
1022:             */
1023:            protected Object readVariableSizeData(char dataType)
1024:                    throws IOException {
1025:                int instances = readInteger();
1026:
1027:                return readFixedSizeData(dataType, instances);
1028:            }
1029:
1030:            /**
1031:             * Resets the file stream by setting its pointer 
1032:             * to the first position after the header.
1033:             *
1034:             */
1035:            public void reset() {
1036:                try {
1037:                    setPosition(1);
1038:                } catch (IOException exc) {
1039:                    // This just means there is nothing in the table
1040:                }
1041:            }
1042:
1043:            /**
1044:             * Close the input stream pointed to by the object
1045:             *  @throws IOException in some unlikely situation
1046:             */
1047:            public void close() throws IOException {
1048:                inputStream.close();
1049:                if (variableIndex != null) {
1050:                    variableIndex.close();
1051:                }
1052:            }
1053:
1054:            /**
1055:             * Sets the position in the stream
1056:             *
1057:             * @param pos A 1-indexed position
1058:             *
1059:             * @throws IOException on any IO failures
1060:             */
1061:            protected void setPosition(long pos) throws IOException {
1062:                if (getRecordSize() < 0) {
1063:                    VariableIndexRow varRow = (VariableIndexRow) variableIndex
1064:                            .readRow((int) pos);
1065:                    inputStream.seek(varRow.getOffset());
1066:                } else {
1067:                    inputStream.seek(getAdjustedHeaderLength()
1068:                            + ((pos - 1) * getRecordSize()));
1069:                }
1070:            }
1071:
1072:            /* (non-Javadoc)
1073:             * @see java.lang.Object#toString()
1074:             */
1075:            public String toString() {
1076:                return featureType.toString();
1077:            }
1078:
1079:            /**
1080:             * Back up a specified number of bytes in the file stream
1081:             *
1082:             * @param bytes a <code>long</code> value
1083:             *
1084:             * @exception IOException if an error occurs
1085:             */
1086:            protected void unread(long bytes) throws IOException {
1087:                inputStream.seek(inputStream.getFilePointer() - bytes);
1088:            }
1089:
1090:            /**
1091:             * Returns the full path of the variable index associated with the current file
1092:             *
1093:             * @return a <code>String</code> value
1094:             */
1095:            private String getVariableIndexFileName() {
1096:                String result = null;
1097:                String fileName = getFileName();
1098:
1099:                if (fileName.toLowerCase().equals(FEATURE_CLASS_SCHEMA_TABLE)) {
1100:                    result = getDirectoryName().concat(File.separator).concat(
1101:                            "fcz");
1102:                } else {
1103:                    result = getDirectoryName().concat(File.separator).concat(
1104:                            fileName.substring(0, fileName.length() - 1) + "x");
1105:                }
1106:
1107:                return result;
1108:            }
1109:
1110:            /* (non-Javadoc)
1111:             * @see org.geotools.feature.FeatureType#find(java.lang.String)
1112:             */
1113:            public int find(String attName) {
1114:                return featureType.find(attName);
1115:            }
1116:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.