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.internal.postgis;
018:
019: import java.io.IOException;
020: import java.io.Serializable;
021: import java.net.URI;
022: import java.net.URISyntaxException;
023: import java.net.URL;
024: import java.sql.Connection;
025: import java.sql.SQLException;
026: import java.util.LinkedList;
027: import java.util.List;
028: import java.util.Map;
029: import java.util.concurrent.locks.Lock;
030:
031: import net.refractions.udig.catalog.CatalogPlugin;
032: import net.refractions.udig.catalog.IResolve;
033: import net.refractions.udig.catalog.IResolveChangeEvent;
034: import net.refractions.udig.catalog.IResolveDelta;
035: import net.refractions.udig.catalog.IService;
036: import net.refractions.udig.catalog.IServiceInfo;
037: import net.refractions.udig.catalog.internal.CatalogImpl;
038: import net.refractions.udig.catalog.internal.ResolveChangeEvent;
039: import net.refractions.udig.catalog.internal.ResolveDelta;
040: import net.refractions.udig.ui.ErrorManager;
041: import net.refractions.udig.ui.UDIGDisplaySafeLock;
042:
043: import org.eclipse.core.runtime.IProgressMonitor;
044: import org.eclipse.core.runtime.NullProgressMonitor;
045: import org.eclipse.core.runtime.SubProgressMonitor;
046: import org.eclipse.jface.resource.ImageDescriptor;
047: import org.eclipse.ui.plugin.AbstractUIPlugin;
048: import org.geotools.data.jdbc.ConnectionPool;
049: import org.geotools.data.postgis.PostgisDataStore;
050: import org.geotools.data.postgis.PostgisDataStoreFactory;
051:
052: /**
053: * Provides ...TODO summary sentence
054: * <p>
055: * TODO Description
056: * </p>
057: *
058: * @author David Zwiers, Refractions Research
059: * @since 0.6
060: */
061: public class PostGISServiceImpl extends IService {
062:
063: private URL url = null;
064: private Map<String, Serializable> params = null;
065: protected Lock rLock = new UDIGDisplaySafeLock();
066:
067: /**
068: * Construct <code>PostGISServiceImpl</code>.
069: *
070: * @param arg1
071: * @param arg2
072: */
073: public PostGISServiceImpl(URL arg1, Map<String, Serializable> arg2) {
074: url = arg1;
075: params = arg2;
076: }
077:
078: /*
079: * Required adaptions: <ul> <li>IServiceInfo.class <li>List.class <IGeoResource> </ul>
080: *
081: * @see net.refractions.udig.catalog.IService#resolve(java.lang.Class,
082: * org.eclipse.core.runtime.IProgressMonitor)
083: */
084: public <T> T resolve(Class<T> adaptee, IProgressMonitor monitor)
085: throws IOException {
086: if (monitor == null)
087: monitor = new NullProgressMonitor();
088:
089: if (adaptee == null) {
090: throw new NullPointerException("No adaptor specified"); //$NON-NLS-1$
091: }
092: if (adaptee.isAssignableFrom(PostgisDataStore.class))
093: return adaptee.cast(getDS());
094: if (adaptee.isAssignableFrom(Connection.class)) {
095: Connection connection;
096: try {
097: connection = getDS().getConnectionPool()
098: .getConnection();
099: } catch (SQLException e) {
100: throw (IOException) new IOException(e
101: .getLocalizedMessage()).initCause(e);
102: }
103: return adaptee.cast(connection);
104: }
105: return super .resolve(adaptee, monitor);
106: }
107:
108: /*
109: * @see net.refractions.udig.catalog.IResolve#canResolve(java.lang.Class)
110: */
111: public <T> boolean canResolve(Class<T> adaptee) {
112: if (adaptee == null)
113: return false;
114: return adaptee.isAssignableFrom(PostgisDataStore.class)
115: || adaptee.isAssignableFrom(Connection.class)
116: || super .canResolve(adaptee);
117: }
118:
119: public void dispose(IProgressMonitor monitor) {
120: if (members == null)
121: return;
122:
123: int steps = (int) ((double) 99 / (double) members.size());
124: for (IResolve resolve : members) {
125: try {
126: SubProgressMonitor subProgressMonitor = new SubProgressMonitor(
127: monitor, steps);
128: resolve.dispose(subProgressMonitor);
129: subProgressMonitor.done();
130: } catch (Throwable e) {
131: ErrorManager
132: .get()
133: .displayException(
134: e,
135: "Error disposing members of service: " + getIdentifier(), CatalogPlugin.ID); //$NON-NLS-1$
136: }
137: }
138: }
139:
140: /*
141: * @see net.refractions.udig.catalog.IResolve#members(org.eclipse.core.runtime.IProgressMonitor)
142: */
143: public List<PostGISGeoResource> members(IProgressMonitor monitor)
144: throws IOException {
145:
146: PostgisDataStore ds = getDS();
147: rLock.lock();
148: try {
149: if (members == null) {
150: members = new LinkedList<PostGISGeoResource>();
151: String[] typenames = ds.getTypeNames();
152: if (typenames != null)
153: for (int i = 0; i < typenames.length; i++) {
154: members.add(new PostGISGeoResource(this ,
155: typenames[i]));
156: }
157: }
158: } finally {
159: rLock.unlock();
160: }
161: return members;
162: }
163:
164: private volatile List<PostGISGeoResource> members = null;
165:
166: /*
167: * @see net.refractions.udig.catalog.IService#getInfo(org.eclipse.core.runtime.IProgressMonitor)
168: */
169: public IServiceInfo getInfo(IProgressMonitor monitor)
170: throws IOException {
171: getDS(); // load ds
172: if (info == null && ds != null) {
173: rLock.lock();
174: try {
175: if (info == null) {
176: info = new IServicePostgisInfo(ds);
177: }
178: } finally {
179: rLock.unlock();
180: }
181: IResolveDelta delta = new ResolveDelta(this ,
182: IResolveDelta.Kind.CHANGED);
183: ((CatalogImpl) CatalogPlugin.getDefault().getLocalCatalog())
184: .fire(new ResolveChangeEvent(this ,
185: IResolveChangeEvent.Type.POST_CHANGE, delta));
186: }
187: return info;
188: }
189:
190: private volatile IServiceInfo info = null;
191:
192: /*
193: * @see net.refractions.udig.catalog.IService#getConnectionParams()
194: */
195: public Map<String, Serializable> getConnectionParams() {
196: return params;
197: }
198:
199: private Throwable msg = null;
200: private volatile PostgisDataStore ds = null;
201: private Lock dsInstantiationLock = new UDIGDisplaySafeLock();
202:
203: PostgisDataStore getDS() throws IOException {
204: boolean changed = false;
205: dsInstantiationLock.lock();
206: try {
207: if (ds == null) {
208: changed = true;
209: // PostgisDataStoreFactory dsf = new PostgisDataStoreFactory();
210: PostgisDataStoreFactory dsf = new PostgisDataStoreFactory();
211: if (dsf.canProcess(params)) {
212: try {
213: ds = (PostgisDataStore) dsf
214: .createDataStore(params);
215: } catch (IOException e) {
216: msg = e;
217: throw e;
218: }
219: }
220: }
221: } finally {
222: dsInstantiationLock.unlock();
223: }
224: if (changed) {
225: IResolveDelta delta = new ResolveDelta(this ,
226: IResolveDelta.Kind.CHANGED);
227: ((CatalogImpl) CatalogPlugin.getDefault().getLocalCatalog())
228: .fire(new ResolveChangeEvent(this ,
229: IResolveChangeEvent.Type.POST_CHANGE, delta));
230: }
231: if (ds != null) {
232: PostgisPlugin.addDataStore(ds);
233: }
234: return ds;
235: }
236:
237: /*
238: * @see net.refractions.udig.catalog.IResolve#getStatus()
239: */
240: public Status getStatus() {
241: return msg != null ? Status.BROKEN
242: : ds == null ? Status.NOTCONNECTED : Status.CONNECTED;
243: }
244:
245: /*
246: * @see net.refractions.udig.catalog.IResolve#getMessage()
247: */
248: public Throwable getMessage() {
249: return msg;
250: }
251:
252: /*
253: * @see net.refractions.udig.catalog.IResolve#getIdentifier()
254: */
255: public URL getIdentifier() {
256: return url;
257: }
258:
259: private class IServicePostgisInfo extends IServiceInfo {
260:
261: IServicePostgisInfo(PostgisDataStore resource) {
262: super ();
263: String[] tns = null;
264: try {
265: tns = resource.getTypeNames();
266: } catch (IOException e) {
267: PostgisPlugin.log("Unable to read typenames", e); //$NON-NLS-1$
268: tns = new String[0];
269: }
270: keywords = new String[tns.length + 1];
271:
272: System.arraycopy(tns, 0, keywords, 1, tns.length);
273: keywords[0] = "postgis"; //$NON-NLS-1$
274:
275: try {
276: schema = new URI("jdbc://postgis/gml"); //$NON-NLS-1$
277: } catch (URISyntaxException e) {
278: PostgisPlugin.log(null, e);
279: }
280: }
281:
282: public String getDescription() {
283: return getIdentifier().toString();
284: }
285:
286: public URL getSource() {
287: return getIdentifier();
288: }
289:
290: public String getTitle() {
291: return "PostGIS " + getIdentifier().getHost(); //$NON-NLS-1$
292: }
293:
294: public ImageDescriptor getIcon() {
295: return AbstractUIPlugin.imageDescriptorFromPlugin(
296: PostgisPlugin.ID, "icons/obj16/postgis_16.gif"); //$NON-NLS-1$
297: }
298: }
299: }
|