/** * Put together a map of VPF files and their corresponding TableRows * * @param file * @param row */ private Map generateFileRowMap(VPFFile file, SimpleFeature row) throws IOException { String tileFileName = null; Map rows = new HashMap(); rows.put(file, row); Iterator joinIter = featureType.getFeatureClass().getJoinList().iterator(); while (joinIter.hasNext()) { ColumnPair columnPair = (ColumnPair) joinIter.next(); VPFFile primaryFile = getVPFFile(columnPair.column1); VPFFile joinFile = null; joinFile = getVPFFile(columnPair.column2); if (!rows.containsKey(joinFile) && rows.containsKey(primaryFile)) { SimpleFeature joinRow = (SimpleFeature) rows.get(primaryFile); try { int joinID = Integer.parseInt(joinRow.getAttribute(columnPair.column1.getName()).toString()); rows.put( joinFile, getVPFFile(columnPair.column2).getRowFromId(columnPair.column2.getName(), joinID)); } catch (NullPointerException exc) { // Non-matching joins - just put in a NULL rows.put(joinFile, null); } catch (IllegalAttributeException exc) { // I really don't expect to see this one exc.printStackTrace(); rows.put(joinFile, null); } } } return rows; }
/** * Read a row and determine if it matches the feature type Three possibilities here: row is null * -- hasNext = false, do not try again row matches -- hasNext = true, do not try again row does * not match -- hasNext is undefined because we must try again * * @return Whether we need to read again */ private boolean readNext() throws IOException { boolean result = true; VPFFile file = (VPFFile) featureType.getFeatureClass().getFileList().get(0); hasNext = false; SimpleFeature row = null; try { if (file.hasNext()) { row = file.readFeature(); } } catch (IOException exc1) { // TODO Auto-generated catch block exc1.printStackTrace(); } catch (IllegalAttributeException exc1) { // TODO Auto-generated catch block exc1.printStackTrace(); } if ((row == null)) { hasNext = false; result = false; } // Exclude objects with a different FACC Code else if (featureType.getFaccCode() != null) { try { Object temp = null; for (int i = 0; temp == null && i < ALLOWED_FCODE_ATTRIBUTES.length; i++) { temp = row.getAttribute(ALLOWED_FCODE_ATTRIBUTES[i]); } String faccCode = temp.toString().trim(); if (featureType.getFaccCode().equals(faccCode)) { retrieveObject(file, row); hasNext = true; result = false; } } catch (RuntimeException exc) { // Ignore this case because it typically means the f_code is invalid } } return result; }
/** * Returns the VPFFile for a particular column. It will only find the first match, but that should * be okay because duplicate columns will cause even bigger problems elsewhere. * * @param column the column to search for * @return the VPFFile that owns this column */ private VPFFile getVPFFile(AttributeDescriptor column) { Name columnName = column.getName(); VPFFile result = null; VPFFile temp; Iterator<VPFFile> iter = featureType.getFeatureClass().getFileList().iterator(); while (iter.hasNext()) { temp = iter.next(); if ((temp != null) && (temp.getColumn(columnName.getLocalPart()) != null)) { result = temp; break; } } return result; }
/** * Returns the VPFFile for a particular column. It will only find the first match, but that should * be okay because duplicate columns will cause even bigger problems elsewhere. * * @param column the column to search for * @return the VPFFile that owns this column */ private VPFFile getVPFFile(VPFColumn column) { String columnName = column.getName(); VPFFile result = null; VPFFile temp; Iterator<VPFFile> iter = featureType.getFeatureClass().getFileList().iterator(); while (iter.hasNext()) { temp = (VPFFile) iter.next(); if ((temp != null) && (temp.getColumn(columnName) != null)) { result = temp; break; } } return result; }
/** Need to reset the stream for the next time Resets the iterator by resetting the stream. */ public void reset() { VPFFile file = (VPFFile) featureType.getFeatureClass().getFileList().get(0); file.reset(); VPFFileFactory.getInstance().reset(); }
/** * Get the values from all of the columns based on their presence (or absense) in the rows * * <p>Potential cases: simple column join column non-matching join null value geometry * * @param file the file * @param row the row */ private void retrieveObject(VPFFile file, SimpleFeature row) throws IOException { VPFFile secondFile = null; VPFColumn column = null; Map rows = generateFileRowMap(file, row); List<AttributeDescriptor> attributes = featureType.getFeatureClass().getAttributeDescriptors(); Object[] values = new Object[featureType.getAttributeCount()]; Object value = null; String featureId = null; // Pass 1 - identify the feature identifier for (int inx = 0; inx < attributes.size(); inx++) { // I am thinking it is probably safer to look this up // by column name than by position, but if it breaks, // it is easy enough to change if (attributes.get(inx).getLocalName().equals("id")) { value = row.getAttribute(inx); if (value != null) { featureId = value.toString(); } break; } } try { currentFeature = SimpleFeatureBuilder.build(featureType, values, featureId); } catch (IllegalAttributeException exc) { // This shouldn't happen since everything should be nillable exc.printStackTrace(); } // Pass 2 - get the attributes, including the geometry for (int inx = 0; inx < attributes.size(); inx++) { try { if (attributes .get(inx) .getLocalName() .equals(AnnotationFeatureType.ANNOTATION_ATTRIBUTE_NAME)) { try { // TODO: are we sure this is the intended action? Hard-coding an attribute to "nam"? currentFeature.setAttribute(inx, "nam"); } catch (IllegalAttributeException exc) { exc.printStackTrace(); } continue; } column = (VPFColumn) attributes.get(inx); value = null; secondFile = getVPFFile(column); SimpleFeature tempRow = (SimpleFeature) rows.get(secondFile); if (tempRow != null) { value = tempRow.getAttribute(column.getName()); if (column.isAttemptLookup()) { try { // Attempt to perform a lookup and conversion String featureClassName = getVPFFile(column).getFileName(); String intVdtFileName = featureType .getFeatureClass() .getDirectoryName() .concat(File.separator) .concat("int.vdt"); VPFFile intVdtFile = VPFFileFactory.getInstance().getFile(intVdtFileName); Iterator intVdtIter = intVdtFile.readAllRows().iterator(); while (intVdtIter.hasNext()) { SimpleFeature intVdtRow = (SimpleFeature) intVdtIter.next(); if (intVdtRow.getAttribute("table").toString().trim().equals(featureClassName) && (Short.parseShort(intVdtRow.getAttribute("value").toString()) == Short.parseShort(value.toString()) && (intVdtRow .getAttribute("attribute") .toString() .trim() .equals(column.getName())))) { value = intVdtRow.getAttribute("description").toString().trim(); break; } } // If there is a problem, forget about mapping and continue } catch (IOException exc) { } catch (RuntimeException exc) { } } } try { currentFeature.setAttribute(inx, value); } catch (ArrayIndexOutOfBoundsException exc) { // TODO Auto-generated catch block exc.printStackTrace(); } catch (IllegalAttributeException exc) { // TODO Auto-generated catch block exc.printStackTrace(); } } catch (ClassCastException exc2) { try { // This is the area geometry case featureType .getFeatureClass() .getGeometryFactory() .createGeometry(featureType, currentFeature); } catch (IllegalAttributeException exc) { // TODO Auto-generated catch block exc.printStackTrace(); } catch (SQLException exc) { // TODO Auto-generated catch block exc.printStackTrace(); } } } }