001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.catalog.hsql.internal;
018:
019: import java.io.IOException;
020: import java.net.MalformedURLException;
021: import java.net.URI;
022: import java.net.URL;
023:
024: import net.refractions.udig.catalog.CatalogPlugin;
025: import net.refractions.udig.catalog.IGeoResource;
026: import net.refractions.udig.catalog.IGeoResourceInfo;
027: import net.refractions.udig.catalog.IService;
028: import net.refractions.udig.ui.graphics.Glyph;
029:
030: import org.eclipse.core.runtime.IProgressMonitor;
031: import org.eclipse.core.runtime.IStatus;
032: import org.geotools.data.DataSourceException;
033: import org.geotools.data.FeatureReader;
034: import org.geotools.data.FeatureSource;
035: import org.geotools.data.FeatureStore;
036: import org.geotools.feature.Feature;
037: import org.geotools.feature.FeatureIterator;
038: import org.geotools.feature.FeatureType;
039: import org.geotools.geometry.jts.ReferencedEnvelope;
040: import org.geotools.resources.CRSUtilities;
041: import org.opengis.referencing.crs.CoordinateReferenceSystem;
042:
043: import com.vividsolutions.jts.geom.Envelope;
044:
045: /**
046: * Provides ...TODO summary sentence
047: * <p>
048: * TODO Description
049: * </p>
050: * @author David Zwiers, Refractions Research
051: * @since 0.6
052: */
053: public class HsqlGeoResource extends IGeoResource {
054: HsqlServiceImpl parent;
055: String typename = null;
056:
057: private HsqlGeoResource() {/*not for use*/
058: }
059:
060: /**
061: * Construct <code>PostGISGeoResource</code>.
062: *
063: * @param parent
064: * @param typename
065: */
066: public HsqlGeoResource(HsqlServiceImpl parent, String typename) {
067: this .parent = parent;
068: this .typename = typename;
069: }
070:
071: public URL getIdentifier() {
072: try {
073: return new URL(parent.getIdentifier().toString()
074: + "#" + typename); //$NON-NLS-1$
075: } catch (MalformedURLException e) {
076: return parent.getIdentifier();
077: }
078: }
079:
080: /*
081: * @see net.refractions.udig.catalog.IGeoResource#getStatus()
082: */
083: public Status getStatus() {
084: return parent.getStatus();
085: }
086:
087: /*
088: * @see net.refractions.udig.catalog.IGeoResource#getStatusMessage()
089: */
090: public Throwable getMessage() {
091: return parent.getMessage();
092: }
093:
094: /*
095: * Required adaptions:
096: * <ul>
097: * <li>IGeoResourceInfo.class
098: * <li>IService.class
099: * </ul>
100: * @see net.refractions.udig.catalog.IResolve#resolve(java.lang.Class, org.eclipse.core.runtime.IProgressMonitor)
101: */
102: public <T> T resolve(Class<T> adaptee, IProgressMonitor monitor)
103: throws IOException {
104: if (adaptee == null)
105: return null;
106: // if(adaptee.isAssignableFrom(IService.class))
107: // return adaptee.cast(parent);
108: if (adaptee.isAssignableFrom(IGeoResourceInfo.class))
109: return adaptee.cast(getInfo(monitor));
110: if (adaptee.isAssignableFrom(IGeoResource.class))
111: return adaptee.cast(this );
112: if (adaptee.isAssignableFrom(FeatureStore.class)) {
113: FeatureSource fs = parent.getDS(monitor).getFeatureSource(
114: typename);
115: if (fs instanceof FeatureStore)
116: return adaptee.cast(fs);
117: if (adaptee.isAssignableFrom(FeatureSource.class))
118: return adaptee.cast(parent.getDS(monitor)
119: .getFeatureSource(typename));
120: }
121: return super .resolve(adaptee, monitor);
122: }
123:
124: public IService service(IProgressMonitor monitor)
125: throws IOException {
126: return parent;
127: }
128:
129: /*
130: * @see net.refractions.udig.catalog.IResolve#canResolve(java.lang.Class)
131: */
132: public <T> boolean canResolve(Class<T> adaptee) {
133: if (adaptee == null)
134: return false;
135: return (adaptee.isAssignableFrom(IGeoResourceInfo.class)
136: || adaptee.isAssignableFrom(FeatureStore.class)
137: || adaptee.isAssignableFrom(FeatureSource.class) || adaptee
138: .isAssignableFrom(IService.class))
139: || super .canResolve(adaptee);
140: }
141:
142: private volatile IGeoResourceInfo info;
143:
144: public IGeoResourceInfo getInfo(IProgressMonitor monitor)
145: throws IOException {
146: if (info == null && getStatus() != Status.BROKEN) {
147: parent.rLock.lock();
148: try {
149: if (info == null) {
150: info = new HsqlResourceInfo();
151: }
152: } finally {
153: parent.rLock.unlock();
154: }
155: }
156: return info;
157: }
158:
159: class HsqlResourceInfo extends IGeoResourceInfo {
160:
161: private FeatureType ft = null;
162:
163: HsqlResourceInfo() throws IOException {
164: try {
165: ft = parent.getDS(null).getSchema(typename);
166: } catch (DataSourceException e) {
167: return;
168: }
169:
170: try {
171:
172: FeatureSource source = parent.getDS(null)
173: .getFeatureSource(typename);
174: bounds = (ReferencedEnvelope) source.getBounds();
175: if (bounds == null) {
176: CoordinateReferenceSystem crs = source.getSchema()
177: .getDefaultGeometry().getCoordinateSystem();
178:
179: //try getting an envelope out of the crs
180: org.opengis.spatialschema.geometry.Envelope envelope = CRSUtilities
181: .getEnvelope(crs);
182:
183: if (envelope != null) {
184: bounds = new ReferencedEnvelope(new Envelope(
185: envelope.getLowerCorner()
186: .getOrdinate(0), envelope
187: .getLowerCorner()
188: .getOrdinate(1), envelope
189: .getUpperCorner()
190: .getOrdinate(0), envelope
191: .getUpperCorner()
192: .getOrdinate(1)), crs);
193: } else {
194: //TODO: perhaps access a preference which indicates
195: // wether to do a full table scan
196: //bounds = new ReferencedEnvelope(new Envelope(),crs);
197: //as a last resort do the full scan
198: bounds = new ReferencedEnvelope(new Envelope(),
199: crs);
200: FeatureIterator iter = source.getFeatures()
201: .features();
202: try {
203: while (iter.hasNext()) {
204: Feature element = iter.next();
205: if (bounds.isNull())
206: bounds.init(element.getBounds());
207: else
208: bounds.expandToInclude(element
209: .getBounds());
210: }
211: } finally {
212: iter.close();
213: }
214: }
215: }
216: } catch (DataSourceException e) {
217: //do nothing
218: } catch (Exception e) {
219: CatalogPlugin
220: .getDefault()
221: .getLog()
222: .log(
223: new org.eclipse.core.runtime.Status(
224: IStatus.WARNING,
225: "net.refractions.udig.catalog", 0, Messages.HsqlGeoResource_error_layer_bounds, e)); //$NON-NLS-1$
226: bounds = new ReferencedEnvelope(new Envelope(), null);
227: }
228:
229: icon = Glyph.icon(ft);
230:
231: keywords = new String[] { "hsql", //$NON-NLS-1$
232: ft.getTypeName(), ft.getNamespace().toString() };
233: }
234:
235: public CoordinateReferenceSystem getCRS() {
236: return ft.getDefaultGeometry().getCoordinateSystem();
237: }
238:
239: public String getName() {
240: return ft.getTypeName();
241: }
242:
243: public URI getSchema() {
244: return ft.getNamespace();
245: }
246:
247: public String getTitle() {
248: return ft.getTypeName();
249: }
250: }
251: }
|