001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.visualweb.dataconnectivity.sql;
042:
043: import java.io.InputStream;
044: import java.io.IOException;
045: import java.io.OutputStream;
046: import java.text.MessageFormat;
047: import java.util.ArrayList;
048: import java.util.HashMap;
049: import java.util.Iterator;
050: import java.util.List;
051: import java.util.Locale;
052: import java.util.Map;
053: import java.util.ResourceBundle;
054: import javax.naming.Binding;
055: import javax.naming.CompositeName;
056: import javax.naming.Context;
057: import javax.naming.InitialContext;
058: import javax.naming.NamingEnumeration;
059: import javax.naming.NamingException;
060: import javax.naming.NameAlreadyBoundException;
061: import javax.naming.NameNotFoundException;
062: import javax.xml.parsers.SAXParser;
063: import javax.xml.parsers.SAXParserFactory;
064: import org.netbeans.api.db.explorer.ConnectionManager;
065: import org.netbeans.api.db.explorer.DatabaseConnection;
066: import org.netbeans.api.project.Project;
067: import org.netbeans.modules.visualweb.api.j2ee.common.RequestedJdbcResource;
068: import org.netbeans.modules.visualweb.api.j2ee.common.RequestedResource;
069: import org.netbeans.modules.visualweb.dataconnectivity.datasource.CurrentProject;
070: import org.netbeans.modules.visualweb.dataconnectivity.datasource.DataSourceResolver;
071: import org.netbeans.modules.visualweb.dataconnectivity.model.DataSourceInfo;
072: import org.netbeans.modules.visualweb.dataconnectivity.model.ProjectDataSourceManager;
073: import org.netbeans.modules.visualweb.dataconnectivity.naming.DatabaseSettingsImporter;
074: import org.netbeans.modules.visualweb.dataconnectivity.project.datasource.ProjectDataSourceTracker;
075: import org.netbeans.modules.visualweb.dataconnectivity.utils.ImportDataSource;
076: import org.netbeans.modules.visualweb.project.jsf.api.JsfProjectUtils;
077: import org.netbeans.modules.visualweb.project.jsf.services.DesignTimeDataSourceService;
078: import org.openide.util.Lookup;
079: import org.openide.util.Utilities;
080: import org.xml.sax.Attributes;
081: import org.xml.sax.helpers.DefaultHandler;
082: import org.xml.sax.SAXException;
083: import org.xml.sax.SAXNotRecognizedException;
084:
085: /**
086: * Helper class used by server navigator. Helps manage
087: * datasources in Creator's naming context.
088: *
089: * @author John Kline, John Baker
090: */
091: public class DesignTimeDataSourceHelper {
092:
093: private static ResourceBundle rb = ResourceBundle
094: .getBundle(
095: "org.netbeans.modules.visualweb.dataconnectivity.sql.Bundle",
096: Locale.getDefault());
097: private volatile boolean firstTimeShowAlert = false;
098:
099: private static final String DS_SUBCTX = "java:comp/env/jdbc"; // NOI18N
100: private static final String ROOT_TAG = "dataSources"; // NOI18N
101: private static final String ATTR_MAJ_VER = "majVer"; // NOI18N
102: private static final String ATTR_MIN_VER = "minVer"; // NOI18N
103: private static final String DATASOURCE_TAG = "dataSource"; // NOI18N
104: private static final String ATTR_NAME = "name"; // NOI18N
105: private static final String ATTR_DRIVER = "driverClassName"; // NOI18N
106: private static final String ATTR_URL = "url"; // NOI18N
107: private static final String ATTR_USERNAME = "username"; // NOI18N
108: private static final String ATTR_PASSWORD = "password"; // NOI18N
109: private static final String ATTR_QUERY = "validationQuery"; // NOI18N
110: private static final String ATTR_REFERENCES = "references";
111: private DesignTimeDataSource[] dataSources;
112: private String[] dataSourceNames;
113: private boolean isDataSourceAdded;
114: private Context ctx;
115:
116: public DesignTimeDataSourceHelper() throws NamingException {
117: dataSources = null;
118: dataSourceNames = null;
119: isDataSourceAdded = false;
120: ctx = new InitialContext();
121: }
122:
123: public DataSourceExport[] getDataSourceExports()
124: throws NamingException {
125: getDataSources();
126:
127: ArrayList exports = new ArrayList();
128: /* !JK - the following is not good if the datasource list changes
129: * but the server navigator won't be adding/changing/deleting datasources
130: * while doing this
131: */
132: for (int i = 0; i < dataSources.length; i++) {
133: DesignTimeDataSource ds = dataSources[i];
134:
135: if (!(ds instanceof DesignTimeDataSourceAlias)) {
136: DataSourceExport dse = new DataSourceExport(
137: dataSourceNames[i], ds.getDriverClassName(), ds
138: .getUrl(), ds.getUsername(), ds
139: .getPassword(), ds.getValidationQuery());
140: exports.add(dse);
141: } else {
142: DataSourceExport dse = new DataSourceExport(
143: dataSourceNames[i],
144: ((DesignTimeDataSourceAlias) ds).getAlias());
145: exports.add(dse);
146: }
147: }
148: return (DataSourceExport[]) exports
149: .toArray(new DataSourceExport[0]);
150: }
151:
152: static public void writeExportDocument(OutputStream os,
153: DataSourceExport[] exports) throws IOException {
154:
155: os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
156: .getBytes("UTF-8")); // NOI18N
157: os.write(("<" + ROOT_TAG + " majVer=\"1\" minVer=\"0\">\n")
158: .getBytes("UTF-8")); // NOI18N
159:
160: for (int i = 0; i < exports.length; i++) {
161: DataSourceExport dse = exports[i];
162: if (dse.isExportable()) {
163: os.write((" <" + DATASOURCE_TAG + " name=\""
164: + DesignTimeDataSource.escapeXML(dse.getName()) // NOI18N
165: + "\"\n").getBytes("UTF-8")); // NOI18N
166:
167: if (dse.isAlias()) {
168: os.write((" "
169: + ATTR_REFERENCES
170: + "=\""
171: + DesignTimeDataSource.escapeXML(dse
172: .getAlias()) // NOI18N
173: + "\"\n").getBytes("UTF-8")); // NOI18N
174: } else {
175: if (dse.getDriverClassName() != null) {
176: os.write((" driverClassName=\""
177: + dse.getDriverClassName() // NOI18N
178: + "\"\n").getBytes("UTF-8")); // NOI18N
179: }
180: if (dse.getUrl() != null) {
181: os.write((" url=\""
182: + DesignTimeDataSource.escapeXML(dse
183: .getUrl()) // NOI18N
184: + "\"\n").getBytes("UTF-8")); // NOI18N
185: }
186: if (dse.getValidationQuery() != null) {
187: os.write((" validationQuery=\""
188: + DesignTimeDataSource.escapeXML(dse
189: .getValidationQuery()) // NOI18N
190: + "\"\n").getBytes("UTF-8")); // NOI18N
191: }
192: if (dse.isUsernameExportable()) {
193: if (dse.getUsername() != null) {
194: os.write((" username=\""
195: + dse.getUsername() // NOI18N
196: + "\"\n").getBytes("UTF-8")); // NOI18N
197: }
198: if (dse.isPasswordExportable()) {
199: if (dse.getPassword() != null) {
200: os.write((" password=\"" // NOI18N
201: + DesignTimeDataSource
202: .encryptPassword(dse
203: .getPassword())
204: //!JK + dse.getPassword()
205: + "\"\n").getBytes("UTF-8")); // NOI18N
206: }
207: }
208: }
209: }
210: os.write(" />\n".getBytes("UTF-8")); // NOI18N
211: }
212: }
213: os.write(("</" + ROOT_TAG + ">\n").getBytes("UTF-8")); // NOI18N
214: }
215:
216: static public DataSourceImport[] getDataSourceImports(InputStream is)
217: throws IOException, SAXException {
218:
219: final ArrayList list = new ArrayList();
220: try {
221: SAXParserFactory factory = SAXParserFactory.newInstance();
222: factory.setNamespaceAware(true);
223: factory.setValidating(false);
224: SAXParser parser = factory.newSAXParser();
225: parser.parse(is, new DefaultHandler() {
226: public void startElement(String uri, String localName,
227: String qName, Attributes attributes)
228: throws SAXException {
229: if (qName.equals(ROOT_TAG)) {
230: String majVer = attributes
231: .getValue(ATTR_MAJ_VER);
232: String minVer = attributes
233: .getValue(ATTR_MIN_VER);
234: if (majVer == null
235: || minVer == null
236: || !(majVer.equals("1") && minVer
237: .equals("0"))) { // NOI18N
238: throw new SAXException(
239: MessageFormat
240: .format(
241: rb
242: .getString("ONLY_VER_MAJ_MIN"),
243: new Object[] { "1",
244: "0" })); // NOI18N
245: }
246: } else if (qName.equals(DATASOURCE_TAG)) {
247: String alias = attributes
248: .getValue(ATTR_REFERENCES);
249: String name = attributes.getValue(ATTR_NAME);
250: if (alias == null) {
251: String driverClassName = attributes
252: .getValue(ATTR_DRIVER);
253: String url = attributes.getValue(ATTR_URL);
254: String username = attributes
255: .getValue(ATTR_USERNAME);
256: String password = attributes
257: .getValue(ATTR_PASSWORD);
258: if (password != null) {
259: password = DesignTimeDataSource
260: .decryptPassword(password);
261: }
262: String validationQuery = attributes
263: .getValue(ATTR_QUERY);
264: if (name == null) {
265: throw new SAXException(
266: rb
267: .getString("MISSING_NAME_ATTRIBUTE"));
268: }
269: if (driverClassName == null) {
270: throw new SAXException(
271: rb
272: .getString("MISSING_DRIVER_CLASS_NAME_ATTRIBUTE"));
273: }
274: if (url == null) {
275: throw new SAXException(
276: rb
277: .getString("MISSING_URL_ATTRIBUTE"));
278: }
279: try {
280: list.add(new DataSourceImport(
281: makeUnique(name),
282: driverClassName, url, username,
283: password, validationQuery));
284: } catch (NamingException e) {
285: throw new SAXException(e);
286: }
287: } else {
288: // add the alias.
289: list.add(new DataSourceImport(name, alias));
290: }
291: } else {
292: throw new SAXNotRecognizedException(qName);
293: }
294: }
295:
296: public void endElement(String uri, String localName,
297: String qName) throws SAXException {
298: if (qName.equals(ROOT_TAG)) {
299: } else if (qName.equals(DATASOURCE_TAG)) {
300: } else {
301: throw new SAXNotRecognizedException(qName);
302: }
303: }
304: });
305: } catch (Exception e) {
306: e.printStackTrace();
307: }
308: return (DataSourceImport[]) list
309: .toArray(new DataSourceImport[0]);
310: }
311:
312: static private String makeUnique(String name)
313: throws NamingException {
314: String newName = name;
315: int ctr = 0;
316: while (true) {
317: try {
318: new InitialContext().lookup(newName);
319: ctr++;
320: newName = name + ctr;
321: } catch (NameNotFoundException e) {
322: return newName;
323: }
324: }
325: }
326:
327: public int importDataSources(DataSourceImport[] imports)
328: throws NamingException {
329: int importCount = 0;
330:
331: for (int i = 0; i < imports.length; i++) {
332: DataSourceImport dsi = imports[i];
333: if (dsi.isImportable()) {
334: addFullNameDataSource(dsi.getName(), dsi
335: .getDriverClassName(), dsi.getUrl(), dsi
336: .getValidationQuery(), dsi.getUsername(), dsi
337: .getPassword());
338: importCount++;
339: }
340: }
341:
342: refresh();
343: return importCount;
344: }
345:
346: public String[] getDataSourceNames() throws NamingException {
347: if (dataSourceNames == null) {
348: getDataSources();
349: }
350: return dataSourceNames;
351: }
352:
353: public DesignTimeDataSource[] getDataSources()
354: throws NamingException {
355: if (dataSources == null) {
356:
357: ArrayList both = getAllDataSourceBindings();
358: ArrayList dataSourceList = new ArrayList();
359: ArrayList dataSourceNameList = new ArrayList();
360: for (int icnt = 0; icnt < both.size(); icnt++) {
361: dataSourceList.add(((Binding) both.get(icnt))
362: .getObject());
363: dataSourceNameList.add(((Binding) both.get(icnt))
364: .getName());
365: }
366: dataSources = (DesignTimeDataSource[]) dataSourceList
367: .toArray(new DesignTimeDataSource[0]);
368: dataSourceNames = (String[]) dataSourceNameList
369: .toArray(new String[0]);
370:
371: }
372: return dataSources;
373:
374: }
375:
376: /***
377: * Compose list of all data sources.
378: * @returns an ArrayList of Binding objects
379: */
380: public ArrayList getAllDataSourceBindings() throws NamingException {
381: return getNamesAndDataSources(ctx, DS_SUBCTX, "");
382: }
383:
384: public ArrayList getNamesAndDataSources(Context curCtx,
385: String startName, String dsNamePrefix)
386: throws NamingException {
387: String nodeName = null;
388: ArrayList retVal = new ArrayList();
389:
390: NamingEnumeration list = curCtx.listBindings(startName);
391: while (list.hasMore()) {
392: Binding binding = (Binding) list.next();
393: String name = binding.getName();
394: if (binding.isRelative()) {
395: // append the name to the startimg name.
396: name = startName + "/" + name; // NOI18N
397: }
398: nodeName = name.substring(name.lastIndexOf("/") + 1);
399: if (binding.getObject() instanceof DesignTimeDataSource) {
400:
401: String dsNodeName = ("".equals(dsNamePrefix) ? ""
402: : dsNamePrefix + "/")
403: + nodeName;
404: retVal.add(new Binding(dsNodeName,
405: (DesignTimeDataSource) binding.getObject()));
406:
407: } else if (binding.getObject() instanceof Context) {
408: // It's a subcontext, so search that.
409: retVal.addAll(getNamesAndDataSources((Context) binding
410: .getObject(), "", dsNamePrefix
411: + ("".equals(dsNamePrefix) ? "" : "/")
412: + nodeName));
413: }
414: }
415: list.close();
416: return retVal;
417: }
418:
419: public DesignTimeDataSource getDataSource(String name)
420: throws NamingException {
421: return getDataSourceFromFullName(DS_SUBCTX + "/" + name); // NOI18N
422: }
423:
424: public DesignTimeDataSource getDataSourceFromFullName(
425: String fullName) throws NamingException {
426: Object obj = ctx.lookup(fullName);
427: if (obj instanceof DesignTimeDataSource) {
428: return (DesignTimeDataSource) obj;
429: }
430: throw new NamingException(MessageFormat.format(rb
431: .getString("NOT_A_DATASOURCE"),
432: new Object[] { fullName }));
433: }
434:
435: public DesignTimeDataSource addDataSource(String name,
436: String driverClassName, String url, String validationQuery,
437: String username, String password) throws NamingException {
438:
439: isDataSourceAdded = true;
440: return addFullNameDataSource(DS_SUBCTX + "/" + name,
441: driverClassName, url, validationQuery, // NOI18N
442: username, password);
443: }
444:
445: public DesignTimeDataSource addFullNameDataSource(String name,
446: String driverClassName, String url, String validationQuery,
447: String username, String password) throws NamingException {
448:
449: DesignTimeDataSource ds = new DesignTimeDataSource(null, false,
450: driverClassName, url, validationQuery, username,
451: password);
452:
453: return addFullNameDataSource(name, ds);
454: }
455:
456: public DesignTimeDataSource addFullNameDataSource(String name,
457: DesignTimeDataSource ds) throws NamingException {
458:
459: try {
460: ctx.bind(name, ds);
461: } catch (NameAlreadyBoundException e) {
462: throw e;
463: } catch (NamingException e) {
464: // perhaps the subcontext does not exist
465: // we'll attempt to create every name on the path
466: // and try to bind one more time
467: CompositeName cname = new CompositeName(name);
468: String subcontext = "";
469: for (int i = 0; i < cname.size() - 1; i++) {
470: subcontext += cname.get(i);
471: try {
472: ctx.createSubcontext(subcontext);
473: } catch (NameAlreadyBoundException e2) {
474: }
475: subcontext += "/"; // NOI18N
476: }
477: ctx.bind(name, ds);
478: }
479: refresh();
480: return ds;
481: }
482:
483: public void deleteDataSource(String name) throws NamingException {
484: String this Name = DS_SUBCTX + "/" + name;
485: ctx.unbind(this Name); // NOI18N
486:
487: // Now clean up the tree
488: // by deleting any empty subcontext nodes above.
489: String[] parts = name.split("/");
490: if (parts.length > 1) {
491: for (int icnt = parts.length - 2; icnt >= 0; icnt--) {
492: int lastOne = this Name.lastIndexOf("/");
493: this Name = this Name.substring(0, lastOne);
494: ArrayList bindings = getNamesAndDataSources(ctx,
495: this Name, "");
496: if (bindings.size() > 0) {
497: // has children, so do not destroy it.
498: break;
499: }
500: // remove sub context.
501: // ctx.destroySubcontext(thisName) ;
502: ctx.unbind(this Name);
503: }
504: }
505: refresh();
506: }
507:
508: /***
509: * Check to see if the name or part of the name is in use.
510: * @returns false means you can bind to this name.
511: *
512: * if you have a datasource with name "a/b" then "a" must be
513: * a subcontext or missing, and "b" must not exist.
514: */
515: public boolean nameInUseInContext(String name) {
516: String this Name = DS_SUBCTX + "/" + name;
517:
518: try {
519: Object obj = ctx.lookup(this Name);
520: // found!
521: return true;
522: } catch (NamingException ne) {
523: if (!(ne instanceof NameNotFoundException)) {
524: return true;
525: }
526: }
527:
528: // Name was not found - now look for subContext values.
529: // so if name was x/y/z, make sure both x/y and x are
530: // instances of Context or not found.
531: String[] parts = name.split("/");
532:
533: for (int icnt = parts.length - 2; icnt >= 0; icnt--) {
534: int lastOne = this Name.lastIndexOf("/");
535: this Name = this Name.substring(0, lastOne);
536: try {
537: Object obj = ctx.lookup(this Name);
538: if (obj instanceof Context) {
539: continue;
540: }
541: return true;
542: } catch (NamingException ne) {
543: if (ne instanceof NameNotFoundException)
544: continue;
545: return true;
546: }
547: }
548:
549: return false;
550: }
551:
552: /*
553: * save() needs to be called explicity if you change a datasource. Adds and
554: * deletions automatically refresh, but changes to a datasource cannot be detected.
555: */
556: public void save() throws NamingException {
557: ctx.addToEnvironment("save-context", "true"); // 2nd arg is ignored // NOI18N
558: }
559:
560: public void refresh() {
561: dataSources = null;
562: dataSourceNames = null;
563: }
564:
565: public Map updateDataSource(Project currentProj) {
566: // Manage the migration of legacy projects
567: if (ImportDataSource.isLegacyProject(currentProj)
568: && JsfProjectUtils.getProjectProperty(currentProj,
569: "migrated").equals("")) {//NOI18N
570: DataSourceResolver.getInstance().updateSettings();
571: JsfProjectUtils.createProjectProperty(currentProj,
572: "migrated", "true");
573: }
574:
575: // Get the data sources in the project then bind them to the project's context
576: String[] dynamicDataSources = ProjectDataSourceTracker
577: .getDynamicDataSources(currentProj);
578: String[] hardCodedDataSources = ProjectDataSourceTracker
579: .getHardcodedDataSources(currentProj);
580: List<RequestedResource> jdbcResources = new ArrayList<RequestedResource>();
581: RequestedJdbcResource jdbcResource = null;
582: List<DesignTimeDataSource> ds = null;
583: Map binding = new HashMap();
584:
585: ProjectDataSourceManager projectDataSourceManager = new ProjectDataSourceManager(
586: currentProj);
587:
588: if (dynamicDataSources.length > 0
589: || hardCodedDataSources.length > 0) {
590: for (String name : dynamicDataSources) {
591: jdbcResource = (projectDataSourceManager
592: .getDataSourceWithName(name.substring(name
593: .lastIndexOf("/") + 1)));
594:
595: if (jdbcResource != null)
596: jdbcResources.add(jdbcResource);
597: }
598:
599: for (String name : hardCodedDataSources) {
600: jdbcResource = (projectDataSourceManager
601: .getDataSourceWithName(name.substring(name
602: .lastIndexOf("/") + 1)));
603:
604: if (jdbcResource != null)
605: jdbcResources.add(jdbcResource);
606: }
607:
608: // Add resource reference to web.xml. If already added then resource is not added.
609: DatabaseSettingsImporter.getInstance().updateWebXml(
610: currentProj, jdbcResources);
611:
612: // Support for Creator 2 projects and a hack - serverplugin not detecting datasources in project
613: if (jdbcResource == null) {
614: RequestedJdbcResource[] resources = null;
615: DataSourceInfo dsInfo = null;
616: DesignTimeDataSourceService dataSourceService = null;
617:
618: for (String name : dynamicDataSources) {
619: List<DataSourceInfo> dataSourcesInfo = DatabaseSettingsImporter
620: .getInstance().getDataSourcesInfo();
621: Iterator it = dataSourcesInfo.iterator();
622: while (it.hasNext()) {
623: dsInfo = (DataSourceInfo) it.next();
624: if (name.equals(DS_SUBCTX + "/VIR")
625: && dsInfo
626: .getUrl()
627: .equals(
628: "jdbc:derby://localhost:1527/sample")) {
629: binding.put(name, new DesignTimeDataSource(
630: null, false, dsInfo
631: .getDriverClassName(),
632: "jdbc:derby://localhost:1527/vir",
633: null, dsInfo.getUsername(), dsInfo
634: .getPassword())); // NOI18N
635: dataSourceService = (DesignTimeDataSourceService) Lookup
636: .getDefault()
637: .lookup(
638: DesignTimeDataSourceService.class);
639: dataSourceService
640: .updateProjectDataSource(
641: currentProj,
642: new RequestedJdbcResource(
643: "jdbc/VIR",
644: dsInfo
645: .getDriverClassName(),
646: "jdbc:derby://localhost:1527/vir",
647: dsInfo
648: .getUsername(),
649: dsInfo
650: .getPassword())); // NOI18N
651: } else if (name.equals(DS_SUBCTX + "/"
652: + dsInfo.getName())) { // NOI18N
653: binding.put(name, new DesignTimeDataSource(
654: null, false, dsInfo
655: .getDriverClassName(),
656: dsInfo.getUrl(), null, dsInfo
657: .getUsername(), dsInfo
658: .getPassword()));
659:
660: dataSourceService = (DesignTimeDataSourceService) Lookup
661: .getDefault()
662: .lookup(
663: DesignTimeDataSourceService.class);
664: dataSourceService.updateProjectDataSource(
665: currentProj,
666: new RequestedJdbcResource("jdbc/" + //NOI18N
667: dsInfo.getName(), dsInfo
668: .getDriverClassName(),
669: dsInfo.getUrl(), dsInfo
670: .getUsername(),
671: dsInfo.getPassword()));
672: }
673: }
674: }
675: } else {
676: // Check if datasource exists in the context. If it doesn't exist then bind the datasource .
677: Iterator it = jdbcResources.iterator();
678: boolean found = false;
679:
680: while (it.hasNext()) {
681: jdbcResource = (RequestedJdbcResource) it.next();
682: String name = ((String) jdbcResource
683: .getResourceName());
684: name = name.substring(name.indexOf("/") + 1);
685: found = false;
686: if (name.equals(DS_SUBCTX + "/VIR")
687: && jdbcResource
688: .getUrl()
689: .equals(
690: "jdbc:derby://localhost:1527/sample")) {
691: binding.put(name, new DesignTimeDataSource(
692: null, false, jdbcResource
693: .getDriverClassName(),
694: "jdbc:derby://localhost:1527/vir",
695: null, jdbcResource.getUsername(),
696: jdbcResource.getPassword())); // NOI18N
697: } else if (!found)
698: binding.put(DS_SUBCTX + "/" + name,
699: new DesignTimeDataSource(null, false,
700: jdbcResource
701: .getDriverClassName(),
702: jdbcResource.getUrl(), null,
703: jdbcResource.getUsername(),
704: jdbcResource.getPassword()));
705: }
706: }
707: }
708:
709: return binding;
710: }
711:
712: public boolean dataSourceAdded() {
713: return isDataSourceAdded;
714: }
715:
716: // Update context with existing project's data sources, if any.
717: public void updateCtxBindings(Map bindings) {
718: Iterator it = bindings.keySet().iterator();
719:
720: try {
721: while (it.hasNext()) {
722: String key = (String) it.next();
723: ctx.bind(key, bindings.get(key));
724: }
725: } catch (NamingException ne) {
726: ne.printStackTrace();
727: }
728: }
729:
730: public boolean datasourcesInProject(Project currentProj) {
731: String[] dynamicDataSources = ProjectDataSourceTracker
732: .getDynamicDataSources(currentProj);
733: String[] hardCodedDataSources = ProjectDataSourceTracker
734: .getHardcodedDataSources(currentProj);
735:
736: if (dynamicDataSources.length > 0
737: || hardCodedDataSources.length > 0)
738: return true;
739: else
740: return false;
741: }
742:
743: public static DataSourceInfo getDsInfo(String dsName) {
744: ProjectDataSourceManager projectDataSourceManager = new ProjectDataSourceManager(
745: CurrentProject.getInstance().getOpenedProject());
746: RequestedJdbcResource jdbcResource = projectDataSourceManager
747: .getDataSourceWithName(dsName);
748:
749: return new DataSourceInfo(dsName, jdbcResource
750: .getDriverClassName(), jdbcResource.getUrl(), null,
751: jdbcResource.getUsername(), jdbcResource.getPassword());
752: }
753:
754: /**
755: * Make sure the connections needed by the data sources have been registered
756: * using DatasourceInfo
757: */
758: public static boolean isFound(DataSourceInfo ds) {
759: boolean found = false;
760:
761: if (ds != null) {
762: String url = ds.getUrl();
763: String username = ds.getUsername();
764: DatabaseConnection[] dbConns = ConnectionManager
765: .getDefault().getConnections();
766: for (int i = 0; i < dbConns.length; i++) {
767: DatabaseConnection dbCon = dbConns[i];
768: String url1 = dbCon.getDatabaseURL();
769: String username1 = dbCon.getUser();
770: if (matchURL(url, url1, true)
771: && Utilities
772: .compareObjects(username, username1)) {
773: found = true;
774: }
775: }
776: }
777: return found;
778: }
779:
780: /**
781: * Make sure the connections needed by the data sources have been registered
782: * using DesignTimeDataSource
783: */
784: public static boolean isFound(DesignTimeDataSource ds) {
785: boolean found = false;
786:
787: if (ds != null) {
788: String url = ds.getUrl();
789: String username = ds.getUsername();
790: DatabaseConnection[] dbConns = ConnectionManager
791: .getDefault().getConnections();
792: for (int i = 0; i < dbConns.length; i++) {
793: DatabaseConnection dbCon = dbConns[i];
794: String url1 = dbCon.getDatabaseURL();
795: String username1 = dbCon.getUser();
796: if (matchURL(url, url1, true)
797: && Utilities
798: .compareObjects(username, username1)) {
799: found = true;
800: }
801: }
802: }
803: return found;
804: }
805:
806: private static boolean matchURL(String jdbcResourceUrl,
807: String dsInfoUrl, boolean ignoreCase) {
808: if (ignoreCase) {
809: jdbcResourceUrl = jdbcResourceUrl.toLowerCase();
810: dsInfoUrl = dsInfoUrl.toLowerCase();
811: }
812: if (jdbcResourceUrl.equals(dsInfoUrl)) {
813: return true;
814: }
815:
816: if (jdbcResourceUrl.contains("derby")) {
817: String newJdbcResourceUrl = jdbcResourceUrl.substring(0,
818: jdbcResourceUrl.lastIndexOf(":"))
819: + jdbcResourceUrl.substring(jdbcResourceUrl
820: .lastIndexOf("/"));
821: if (newJdbcResourceUrl.equals(dsInfoUrl)) {
822: return true;
823: }
824: }
825:
826: int nextIndex = 0;
827: if ((jdbcResourceUrl != null) && (dsInfoUrl != null)) {
828: char[] jdbcResourceUrlChars = jdbcResourceUrl.toCharArray();
829: char[] dsInfoUrlChars = dsInfoUrl.toCharArray();
830: for (int i = 0; i < jdbcResourceUrlChars.length - 1; i++) {
831: if ((jdbcResourceUrlChars[i] != dsInfoUrlChars[i])
832: && jdbcResourceUrlChars[i] == ':') {
833: nextIndex = 1;
834: } else if (jdbcResourceUrlChars[i + nextIndex] != dsInfoUrlChars[i]) {
835: return false;
836: }
837: }
838: }
839: return true;
840: }
841: }
|