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