001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2005, 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.db2;
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.ArrayList;
025: import java.util.HashMap;
026: import java.util.Iterator;
027: import java.util.List;
028: import java.util.Map;
029: import java.util.Set;
030: import java.util.concurrent.locks.Lock;
031:
032: import net.refractions.udig.catalog.CatalogPlugin;
033: import net.refractions.udig.catalog.IResolve;
034: import net.refractions.udig.catalog.IService;
035: import net.refractions.udig.catalog.IServiceInfo;
036: import net.refractions.udig.catalog.db2.DB2Plugin;
037: import net.refractions.udig.ui.ErrorManager;
038: import net.refractions.udig.ui.UDIGDisplaySafeLock;
039:
040: import org.eclipse.core.runtime.IProgressMonitor;
041: import org.eclipse.core.runtime.NullProgressMonitor;
042: import org.eclipse.core.runtime.SubProgressMonitor;
043: import org.eclipse.jface.resource.ImageDescriptor;
044: import org.eclipse.ui.plugin.AbstractUIPlugin;
045: import org.geotools.data.DataStore;
046: import org.geotools.data.db2.DB2DataStore;
047: import org.geotools.data.db2.DB2DataStoreFactory;
048:
049: /**
050: * Service handle for the DB2 Universal Database.
051: *
052: * @author Justin Deoliveira,Refractions Research Inc.,jdeolive@refractions.net
053: */
054: public class DB2Service extends IService {
055:
056: /** underlying datastore * */
057: private volatile DB2DataStore ds;
058:
059: /** info object * */
060: private volatile DB2ServiceInfo info;
061:
062: /** members (tables) * */
063: private volatile List<DB2GeoResource> members;
064:
065: /** service url * */
066: private URL url;
067:
068: /** connection parameters * */
069: private Map<String, Serializable> params;
070:
071: /** any thrown exception * */
072: Throwable msg;
073:
074: protected Lock rLock = new UDIGDisplaySafeLock();
075:
076: private Lock dsInstantiationLock = new UDIGDisplaySafeLock();
077:
078: public DB2Service(URL id, Map<String, Serializable> params2) {
079: url = id;
080: this .params = params2;
081: }
082:
083: public <T> boolean canResolve(Class<T> adaptee) {
084: return adaptee != null
085: && (adaptee.isAssignableFrom(DataStore.class) || super
086: .canResolve(adaptee));
087: }
088:
089: @Override
090: public <T> T resolve(Class<T> adaptee, IProgressMonitor monitor)
091: throws IOException {
092: if (monitor == null)
093: monitor = new NullProgressMonitor();
094: if (adaptee == null) {
095: throw new NullPointerException("No adaptor specified"); //$NON-NLS-1$
096: }
097: if (adaptee.isAssignableFrom(DataStore.class)) {
098: return adaptee.cast(getDataStore(monitor)); // use the monitor!
099: }
100: return super .resolve(adaptee, monitor);
101: }
102:
103: public void dispose(IProgressMonitor monitor) {
104: if (members == null)
105: return;
106:
107: int steps = (int) ((double) 99 / (double) members.size());
108: for (IResolve resolve : members) {
109: try {
110: SubProgressMonitor subProgressMonitor = new SubProgressMonitor(
111: monitor, steps);
112: resolve.dispose(subProgressMonitor);
113: subProgressMonitor.done();
114: } catch (Throwable e) {
115: ErrorManager
116: .get()
117: .displayException(
118: e,
119: "Error disposing members of service: " + getIdentifier(), CatalogPlugin.ID); //$NON-NLS-1$
120: }
121: }
122: }
123:
124: @Override
125: public List<DB2GeoResource> members(IProgressMonitor monitor)
126: throws IOException {
127:
128: if (members == null) {
129: DB2DataStore ds = getDataStore(monitor);
130: if (ds == null)
131: return null;
132:
133: rLock.lock();
134: try {
135: if (members == null) {
136: members = new ArrayList<DB2GeoResource>();
137:
138: String[] names = ds.getTypeNames();
139: if (names == null)
140: return members;
141:
142: for (int i = 0; i < names.length; i++) {
143: members.add(new DB2GeoResource(this , names[i]));
144: }
145: }
146: } finally {
147: rLock.unlock();
148: }
149: } else {
150: monitor.done();
151: }
152: return members;
153: }
154:
155: @Override
156: public Map<String, Serializable> getConnectionParams() {
157: return this .params;
158: }
159:
160: public Status getStatus() {
161: return msg != null ? Status.BROKEN
162: : ds == null ? Status.NOTCONNECTED : Status.CONNECTED;
163: }
164:
165: public Throwable getMessage() {
166: return msg;
167: }
168:
169: public URL getIdentifier() {
170: return url;
171: }
172:
173: @Override
174: public IServiceInfo getInfo(IProgressMonitor monitor)
175: throws IOException {
176: if (this .info == null) {
177: DB2DataStore ds = getDataStore(monitor);
178: if (ds == null)
179: return null;
180:
181: rLock.lock();
182: try {
183: if (info == null) {
184: info = new DB2ServiceInfo(null);
185: }
186: } finally {
187: rLock.unlock();
188: }
189: } else {
190: monitor.done();
191: }
192: return info;
193: }
194:
195: DB2DataStore getDataStore(IProgressMonitor monitor)
196: throws IOException {
197: if (monitor == null)
198: monitor = new NullProgressMonitor();
199:
200: if (this .ds == null) {
201: dsInstantiationLock.lock();
202: try {
203: if (ds == null) {
204: DB2DataStoreFactory dsf = new DB2DataStoreFactory();
205: try {
206: // We expect the port value (key '3') to be a String but some of the
207: // extensions (ArcServiceExtension)
208: // change this from a String to an Integer which causes us to fail.
209: // In order to cope with this, we make a local copy of the parameters and
210: // force the port
211: // value to be a String.
212: // Maybe we should change DB2DataStoreFactory.canProcess to accept either
213: // Integer or
214: // String as valid for port.
215: Map<String, Serializable> paramsLocal = new HashMap<String, Serializable>();
216: Set keys = this .params.keySet();
217: Iterator it = keys.iterator();
218: while (it.hasNext()) {
219: String key = (String) it.next();
220: String value = this .params.get(key)
221: .toString();
222: paramsLocal.put(key, value);
223: }
224:
225: if (dsf.canProcess(paramsLocal)) {
226: this .ds = (DB2DataStore) dsf
227: .createDataStore(paramsLocal);
228: }
229: } catch (IOException e) {
230: msg = e;
231: throw e;
232: }
233: }
234: } finally {
235: dsInstantiationLock.unlock();
236: }
237: }
238:
239: return this .ds;
240: }
241:
242: class DB2ServiceInfo extends IServiceInfo {
243:
244: public DB2ServiceInfo(IProgressMonitor monitor) {
245: super ();
246:
247: // make the type names part of the keyword set
248: String[] tns = null;
249: try {
250: tns = getDataStore(monitor).getTypeNames();
251: } catch (IOException e) {
252: CatalogPlugin.log(e.getLocalizedMessage(), e);
253: tns = new String[0];
254: }
255: if (tns == null)
256: tns = new String[] {};
257:
258: keywords = new String[tns.length + 1];
259: System.arraycopy(tns, 0, keywords, 1, tns.length);
260: keywords[0] = "db2"; //$NON-NLS-1$
261:
262: try {
263: schema = new URI("jdbc://db2/gml"); //$NON-NLS-1$
264: } catch (URISyntaxException e) {
265: CatalogPlugin.log(e.getLocalizedMessage(), e);
266: }
267: }
268:
269: public String getDescription() {
270: return getIdentifier().toString();
271: }
272:
273: public URL getSource() {
274: return getIdentifier();
275: }
276:
277: public String getTitle() {
278: return "DB2 " + getIdentifier().getHost(); //$NON-NLS-1$
279: }
280:
281: public ImageDescriptor getIcon() {
282: return AbstractUIPlugin.imageDescriptorFromPlugin(
283: DB2Plugin.ID, "icons/obj16/db2_16.gif"); //$NON-NLS-1$
284: }
285: }
286: }
|