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: /*
042: * ProjectDataSourceManager.java
043: *
044: * Created on June 6, 2006, 1:33 PM
045: *
046: */
047:
048: package org.netbeans.modules.visualweb.dataconnectivity.model;
049:
050: import org.netbeans.modules.visualweb.api.j2ee.common.RequestedJdbcResource;
051: import com.sun.rave.designtime.DesignBean;
052: import com.sun.rave.designtime.DesignContext;
053: import com.sun.rave.designtime.DesignProject;
054: import org.netbeans.modules.visualweb.project.jsf.services.DesignTimeDataSourceService;
055:
056: import java.io.File;
057: import java.net.URI;
058: import java.net.URISyntaxException;
059: import java.util.ArrayList;
060: import java.util.HashMap;
061: import java.util.HashSet;
062: import java.util.Iterator;
063: import java.util.List;
064: import java.util.Map;
065: import java.util.Set;
066:
067: import org.netbeans.api.project.FileOwnerQuery;
068: import org.netbeans.api.project.Project;
069: import org.netbeans.modules.visualweb.api.j2ee.common.RequestedResource;
070: import org.netbeans.modules.visualweb.dataconnectivity.project.datasource.ProjectDataSourceTracker;
071: import org.netbeans.modules.visualweb.dataconnectivity.sql.DesignTimeDataSource;
072:
073: import org.openide.ErrorManager;
074: import org.openide.filesystems.FileUtil;
075: import org.openide.util.Lookup;
076:
077: /**
078: *
079: * @author marcow
080: */
081: public class ProjectDataSourceManager {
082: private Project project = null;
083: private DesignTimeDataSourceService dataSourceService = null;
084:
085: /**
086: * Creates a new instance of ProjectDataSourceManager
087: */
088: public ProjectDataSourceManager(DesignBean designBean) {
089: DesignContext designContext = designBean.getDesignContext();
090: DesignProject designProject = designContext.getProject();
091: File nbprojectFile = null;
092:
093: try {
094: nbprojectFile = designProject.getResourceFile(new URI(
095: "nbproject")); // NOI18N
096: } catch (URISyntaxException ex) {
097: // Should not happen on a static string
098: ErrorManager.getDefault().notify(
099: ErrorManager.INFORMATIONAL, ex);
100: }
101:
102: if (nbprojectFile != null) {
103: project = FileOwnerQuery.getOwner(FileUtil
104: .toFileObject(nbprojectFile));
105: }
106:
107: dataSourceService = (DesignTimeDataSourceService) Lookup
108: .getDefault().lookup(DesignTimeDataSourceService.class);
109: }
110:
111: // If I the project is known then just construct a new ProjectDataSourceManager with this project
112: public ProjectDataSourceManager(Project project) {
113: this .project = project;
114:
115: dataSourceService = (DesignTimeDataSourceService) Lookup
116: .getDefault().lookup(DesignTimeDataSourceService.class);
117: }
118:
119: /**
120: * Add the datasource meta data to the project
121: */
122: public boolean addDataSource(DataSourceInfo dsInfo) {
123: if ((project != null) && (dataSourceService != null)) {
124: RequestedJdbcResource reqResource = new RequestedJdbcResource(
125: "jdbc/" + // NOI18N
126: dsInfo.getName(), dsInfo
127: .getDriverClassName(), dsInfo.getUrl(),
128: dsInfo.getUsername(), dsInfo.getPassword());
129:
130: if (!dataSourceService.updateProjectDataSource(project,
131: reqResource)) {
132: return false;
133: }
134:
135: // create a JNDI name for resource reference name
136: dataSourceService.updateResourceReference(project,
137: reqResource);
138: }
139:
140: // save data source for project
141: // DataSourceInfoManager.getInstance().addDataSourceInfo(dsInfo);
142: // dsHelper.addFullNameDataSource(dsString, ds.getDataSource() ) ;
143:
144: return true;
145: }
146:
147: /**
148: * Return true if a legacy project's RequestedJdbcResources are available
149: */
150: public boolean isRequestedJdbcResourceAvailable() {
151: RequestedJdbcResource jdbcResource = null;
152: boolean hasResource = false;
153:
154: if (dataSourceService.getProjectDataSources(project).size() > 0) {
155: hasResource = true;
156: }
157:
158: return hasResource;
159: }
160:
161: /**
162: * Find the RequestedJdbcResource based on the information in the provided datasource info
163: * The Url, driver class, user name and password are matched
164: */
165: public Set<RequestedJdbcResource> findRequestedJdbcResources(
166: DataSourceInfo dsInfo) {
167: Set<RequestedJdbcResource> ret = new HashSet<RequestedJdbcResource>();
168:
169: if ((project != null) && (dataSourceService != null)) {
170: // First Search the project data sources
171: Set<RequestedJdbcResource> projectDataSources = dataSourceService
172: .getProjectDataSources(project);
173: Iterator<RequestedJdbcResource> projectDataSourcesIterator = projectDataSources
174: .iterator();
175:
176: while (projectDataSourcesIterator.hasNext()) {
177: RequestedJdbcResource requestedJdbcResource = projectDataSourcesIterator
178: .next();
179:
180: if (matchDataSourceInfo(requestedJdbcResource, dsInfo)) {
181: ret.add(requestedJdbcResource);
182: }
183: }
184: // Now search the server data sources
185: Set<RequestedJdbcResource> serverDataSources = dataSourceService
186: .getServerDataSources(project);
187: Iterator<RequestedJdbcResource> serverDataSourcesIterator = serverDataSources
188: .iterator();
189:
190: while (serverDataSourcesIterator.hasNext()) {
191: RequestedJdbcResource requestedJdbcResource = serverDataSourcesIterator
192: .next();
193:
194: if (matchDataSourceInfo(requestedJdbcResource, dsInfo)) {
195: ret.add(requestedJdbcResource);
196: }
197: }
198: }
199:
200: return ret;
201: }
202:
203: public RequestedJdbcResource getDataSourceWithName(String name) {
204: if ((project != null) && (dataSourceService != null)) {
205: // First Search the project data sources
206: Set<RequestedJdbcResource> projectDataSources = dataSourceService
207: .getProjectDataSources(project);
208: Iterator<RequestedJdbcResource> projectDataSourcesIterator = projectDataSources
209: .iterator();
210:
211: while (projectDataSourcesIterator.hasNext()) {
212: RequestedJdbcResource requestedJdbcResource = projectDataSourcesIterator
213: .next();
214: String resourceName = requestedJdbcResource
215: .getResourceName();
216: String projectDsName = "";
217:
218: // stripDATASOURCE_PREFIX is a hack for JBoss and other application servers due to differences in JNDI string format
219: // for issue 101812
220: if (resourceName.startsWith("jdbc")) { // NOI18N
221: projectDsName = resourceName.replaceFirst("jdbc/",
222: ""); // NOI18N
223: } else if (resourceName.startsWith("java:/jdbc")) {
224: projectDsName = resourceName.replaceFirst(
225: "java:/jdbc/", ""); // NOI18N
226: }
227:
228: if (projectDsName.equals(name)) {
229: return requestedJdbcResource;
230: }
231: }
232:
233: // Now search the server data sources
234: Set<RequestedJdbcResource> serverDataSources = dataSourceService
235: .getServerDataSources(project);
236: Iterator<RequestedJdbcResource> serverDataSourcesIterator = serverDataSources
237: .iterator();
238:
239: while (serverDataSourcesIterator.hasNext()) {
240: RequestedJdbcResource requestedJdbcResource = serverDataSourcesIterator
241: .next();
242: //String projectDsName = requestedJdbcResource.getResourceName().replaceFirst("jdbc/",""); // NOI18N
243: String projectDsName = requestedJdbcResource
244: .getResourceName();
245:
246: // stripDATASOURCE_PREFIX is a hack for JBoss and other application servers due to differences in JNDI string format
247: // for issue 101812
248: if (projectDsName.startsWith("jdbc")) { // NOI18N
249: projectDsName = projectDsName.replaceFirst("jdbc/",
250: ""); // NOI18N
251: } else if (projectDsName.startsWith("java:/jdbc")) {
252: projectDsName = projectDsName.replaceFirst(
253: "java:/jdbc/", ""); // NOI18N
254: }
255:
256: if (projectDsName.equals(name)) {
257: return requestedJdbcResource;
258: }
259: }
260: }
261:
262: return null;
263: }
264:
265: /**
266: * Match the datasource based on Url, driver class, user name and password
267: */
268: public boolean matchDataSourceInfo(
269: RequestedJdbcResource requestedJdbcResource,
270: DataSourceInfo dsInfo) {
271: String url = requestedJdbcResource.getUrl();
272: String driverClassName = requestedJdbcResource
273: .getDriverClassName();
274: String username = requestedJdbcResource.getUsername();
275: String password = requestedJdbcResource.getPassword();
276:
277: String url1 = dsInfo.getUrl();
278: String driverClassName1 = dsInfo.getDriverClassName();
279: String username1 = dsInfo.getUsername();
280: String password1 = dsInfo.getPassword();
281:
282: // hack-around for 6481339/6494241
283: if (matchURL(url, url1, true)
284: && matchString(username, username1, false)
285: && matchString(password, password1, false)) {
286:
287: // plug-in returns the wrong driver class name for MySQL
288: // if (matchString(url, url1, true) && matchString(driverClassName, driverClassName1, false) &&
289: // matchString(username, username1, false) && matchString(password, password1, false)) {
290: return true;
291: } else {
292: return false;
293: }
294: }
295:
296: /**
297: * The strings match if both or null
298: */
299: private boolean matchString(String str1, String str2,
300: boolean ignoreCase) {
301: if ((str1 != null) && (str2 != null)) {
302: if (ignoreCase) {
303: return str1.trim().equalsIgnoreCase(str2.trim());
304: } else {
305: return str1.trim().equals(str2.trim());
306: }
307: } else if ((str1 == null) && (str2 == null)) {
308: return true;
309: } else {
310: return false;
311: }
312: }
313:
314: /**
315: * Separate match method for URLs due to url problems when jdbc url doesn't contain a port #
316: * jbaker hack around for 6481339/6494241
317: */
318: private boolean matchURL(String jdbcResourceUrl, String dsInfoUrl,
319: boolean ignoreCase) {
320: if (ignoreCase) {
321: jdbcResourceUrl = jdbcResourceUrl.toLowerCase();
322: dsInfoUrl = dsInfoUrl.toLowerCase();
323: }
324: if (jdbcResourceUrl.equals(dsInfoUrl)) {
325: return true;
326: }
327:
328: if (jdbcResourceUrl.contains("derby")) {
329: String newJdbcResourceUrl = jdbcResourceUrl.substring(0,
330: jdbcResourceUrl.lastIndexOf(":"))
331: + jdbcResourceUrl.substring(jdbcResourceUrl
332: .lastIndexOf("/"));
333: if (newJdbcResourceUrl.equals(dsInfoUrl)) {
334: return true;
335: }
336: }
337:
338: int nextIndex = 0;
339: if ((jdbcResourceUrl != null) && (dsInfoUrl != null)) {
340: char[] jdbcResourceUrlChars = jdbcResourceUrl.toCharArray();
341: char[] dsInfoUrlChars = dsInfoUrl.toCharArray();
342: for (int i = 0; i < jdbcResourceUrlChars.length - 1; i++) {
343: if ((jdbcResourceUrlChars[i] != dsInfoUrlChars[i])
344: && jdbcResourceUrlChars[i] == ':') {
345: nextIndex = 1;
346: } else if (jdbcResourceUrlChars[i + nextIndex] != dsInfoUrlChars[i]) {
347: return false;
348: }
349: }
350: }
351: return true;
352: }
353:
354: public boolean removeDataSource(DesignProject designProject,
355: DataSourceInfo dsInfo) {
356: // Remove the datasource meta data from the project
357: throw new UnsupportedOperationException(
358: "Missing support in web/project"); // NOI18N
359: }
360:
361: public boolean modifyDataSource(DesignProject designProject,
362: DataSourceInfo dsInfo) {
363: // Modify the datasource meta data in the project if it exists in the project
364: throw new UnsupportedOperationException(
365: "Missing support in web/project"); //NOI18N
366: }
367:
368: }
|