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-2006 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: package org.netbeans.modules.db.explorer;
043:
044: import java.io.InputStream;
045: import java.io.OutputStreamWriter;
046: import java.nio.charset.CharacterCodingException;
047: import java.util.Collection;
048: import java.util.concurrent.CountDownLatch;
049: import org.netbeans.modules.db.explorer.nodes.RootNode;
050: import org.netbeans.modules.db.test.DOMCompare;
051: import org.netbeans.modules.db.test.TestBase;
052: import org.netbeans.modules.db.test.Util;
053: import org.netbeans.modules.db.util.Base64;
054: import org.openide.cookies.InstanceCookie;
055: import org.openide.filesystems.FileChangeAdapter;
056: import org.openide.filesystems.FileEvent;
057: import org.openide.filesystems.FileLock;
058: import org.openide.filesystems.FileObject;
059: import org.openide.loaders.DataFolder;
060: import org.openide.loaders.DataObject;
061: import org.openide.loaders.FolderLookup;
062: import org.openide.util.Lookup;
063: import org.openide.xml.EntityCatalog;
064: import org.openide.xml.XMLUtil;
065: import org.w3c.dom.Document;
066: import org.xml.sax.ErrorHandler;
067: import org.xml.sax.InputSource;
068: import org.xml.sax.SAXException;
069: import org.xml.sax.SAXParseException;
070:
071: /**
072: *
073: * @author Andrei Badea
074: */
075: public class DatabaseConnectionConvertorTest extends TestBase {
076:
077: public DatabaseConnectionConvertorTest(String testName) {
078: super (testName);
079: }
080:
081: protected void setUp() throws Exception {
082: super .setUp();
083: Util.deleteConnectionFiles();
084: }
085:
086: public void testReadXml() throws Exception {
087: FileObject fo = createConnectionFile("connection.xml", Util
088: .getConnectionsFolder());
089: DataObject dobj = DataObject.find(fo);
090: InstanceCookie ic = (InstanceCookie) dobj
091: .getCookie(InstanceCookie.class);
092: assertNotNull(ic);
093:
094: DatabaseConnection conn = (DatabaseConnection) ic
095: .instanceCreate();
096: assertEquals("org.foo.FooDriver", conn.getDriver());
097: assertEquals("foo_driver", conn.getDriverName());
098: assertEquals("jdbc:foo:localhost", conn.getDatabase());
099: assertEquals("schema", conn.getSchema());
100: assertEquals("user", conn.getUser());
101: assertEquals("password", conn.getPassword());
102: assertTrue(conn.rememberPassword());
103: }
104:
105: public void testWriteNullPassword() throws Exception {
106: testWriteXml(null, true, "null-pwd-connection.xml");
107: }
108:
109: public void testWriteXml() throws Exception {
110: testWriteXml("password", true, "bar-connection.xml");
111: }
112:
113: private void testWriteXml(String password, boolean savePassword,
114: String goldenFileName) throws Exception {
115:
116: DatabaseConnection conn = new DatabaseConnection(
117: "org.bar.BarDriver", "bar_driver",
118: "jdbc:bar:localhost", "schema", "user", password,
119: savePassword);
120:
121: DatabaseConnectionConvertor.create(conn);
122:
123: FileObject fo = Util.getConnectionsFolder().getChildren()[0];
124:
125: ErrorHandlerImpl errHandler = new ErrorHandlerImpl();
126: Document doc = null;
127: InputStream input = fo.getInputStream();
128: try {
129: doc = XMLUtil.parse(new InputSource(input), true, true,
130: errHandler, EntityCatalog.getDefault());
131: } finally {
132: input.close();
133: }
134:
135: assertFalse(
136: "DatabaseConnectionConvertor generates invalid XML acc to the DTD!",
137: errHandler.error);
138:
139: Document goldenDoc = null;
140: input = getClass().getResourceAsStream(goldenFileName);
141: try {
142: goldenDoc = XMLUtil.parse(new InputSource(input), true,
143: true, null, EntityCatalog.getDefault());
144: } finally {
145: input.close();
146: }
147:
148: assertTrue(DOMCompare.compareDocuments(doc, goldenDoc));
149: }
150:
151: /**
152: * Tests that the instance retrieved from the DO created by DCC.create(DCI dbconn) is the same object as dbconn.
153: */
154: public void testSameInstanceAfterCreate() throws Exception {
155: DatabaseConnection dbconn = new DatabaseConnection(
156: "org.bar.BarDriver", "bar_driver",
157: "jdbc:bar:localhost", "schema", "user", "password");
158: dbconn.setRememberPassword(true);
159: DataObject dobj = DatabaseConnectionConvertor.create(dbconn);
160: assertSame(dbconn, ((InstanceCookie) dobj
161: .getCookie(InstanceCookie.class)).instanceCreate());
162: }
163:
164: public void testSaveOnPropertyChange() throws Exception {
165: DatabaseConnection dbconn = new DatabaseConnection("a", "b",
166: "c", "d", "e", null);
167: FileObject fo = DatabaseConnectionConvertor.create(dbconn)
168: .getPrimaryFile();
169:
170: class FCL extends FileChangeAdapter {
171:
172: private final CountDownLatch latch = new CountDownLatch(1);
173:
174: public void fileChanged(FileEvent fe) {
175: latch.countDown();
176: }
177:
178: public void await() throws InterruptedException {
179: latch.await();
180: }
181: }
182:
183: FCL fcl = new FCL();
184: fo.addFileChangeListener(fcl);
185:
186: dbconn.setDriver("org.bar.BarDriver");
187: dbconn.setDriverName("bar_driver");
188: dbconn.setDatabase("jdbc:bar:localhost");
189: dbconn.setSchema("schema");
190: dbconn.setUser("user");
191: dbconn.setPassword("password");
192: dbconn.setRememberPassword(true);
193:
194: fcl.await();
195:
196: ErrorHandlerImpl errHandler = new ErrorHandlerImpl();
197: Document doc = null;
198: InputStream input = fo.getInputStream();
199: try {
200: doc = XMLUtil.parse(new InputSource(input), true, true,
201: errHandler, EntityCatalog.getDefault());
202: } finally {
203: input.close();
204: }
205:
206: Document goldenDoc = null;
207: input = getClass().getResourceAsStream("bar-connection.xml");
208: try {
209: goldenDoc = XMLUtil.parse(new InputSource(input), true,
210: true, null, EntityCatalog.getDefault());
211: } finally {
212: input.close();
213: }
214:
215: assertTrue(DOMCompare.compareDocuments(doc, goldenDoc));
216: }
217:
218: public void testLookup() throws Exception {
219: FileObject parent = Util.getConnectionsFolder();
220: createConnectionFile("connection.xml", parent);
221: FolderLookup lookup = new FolderLookup(DataFolder
222: .findFolder(parent));
223: Lookup.Result result = lookup.getLookup().lookup(
224: new Lookup.Template(DatabaseConnection.class));
225: Collection instances = result.allInstances();
226: assertEquals(1, instances.size());
227: }
228:
229: public void testImportOldConnections() throws Exception {
230: DatabaseConnection conn = new DatabaseConnection(
231: "org.foo.FooDriver", "foo_driver",
232: "jdbc:foo:localhost", "schema", "user", null);
233: RootNode.getOption().getConnections().add(conn);
234:
235: DatabaseConnectionConvertor.importOldConnections();
236:
237: FileObject root = Util.getConnectionsFolder();
238: Collection instances = new FolderLookup(DataFolder
239: .findFolder(root)).getLookup().lookup(
240: new Lookup.Template(DatabaseConnection.class))
241: .allInstances();
242: assertEquals(1, instances.size());
243:
244: DatabaseConnection importedConn = (DatabaseConnection) instances
245: .iterator().next();
246: assertEquals(conn.getDriver(), importedConn.getDriver());
247: assertEquals(conn.getDriverName(), importedConn.getDriverName());
248: assertEquals(conn.getDatabase(), importedConn.getDatabase());
249: assertEquals(conn.getSchema(), importedConn.getSchema());
250: assertEquals(conn.getUser(), importedConn.getUser());
251: }
252:
253: public void testDecodePassword() throws Exception {
254: assertNull(DatabaseConnectionConvertor
255: .decodePassword(new byte[0]));
256: assertEquals("password", DatabaseConnectionConvertor
257: .decodePassword("password".getBytes("UTF-8")));
258: try {
259: DatabaseConnectionConvertor.decodePassword(new byte[] {
260: (byte) 0xff, (byte) 0xff, (byte) 0xff });
261: fail();
262: } catch (CharacterCodingException e) {
263: }
264: }
265:
266: private static FileObject createConnectionFile(String name,
267: FileObject folder) throws Exception {
268: FileObject fo = folder.createData(name);
269: FileLock lock = fo.lock();
270: try {
271: OutputStreamWriter writer = new OutputStreamWriter(fo
272: .getOutputStream(lock), "UTF-8");
273: try {
274: writer.write("<?xml version='1.0' encoding='UTF-8'?>");
275: writer
276: .write("<!DOCTYPE connection PUBLIC '-//NetBeans//DTD Database Connection 1.0//EN' 'http://www.netbeans.org/dtds/connection-1_0.dtd'>");
277: writer.write("<connection>");
278: writer
279: .write("<driver-class value='org.foo.FooDriver'/>");
280: writer.write("<driver-name value='foo_driver'/>");
281: writer
282: .write("<database-url value='jdbc:foo:localhost'/>");
283: writer.write("<schema value='schema'/>");
284: writer.write("<user value='user'/>");
285: // This is the Base64 encoded value for the string 'password'
286: writer.write("<password value='"
287: + Base64.byteArrayToBase64("password"
288: .getBytes("UTF-8")) + "'/>");
289: writer.write("</connection>");
290: } finally {
291: writer.close();
292: }
293: } finally {
294: lock.releaseLock();
295: }
296: return fo;
297: }
298:
299: private static final class ErrorHandlerImpl implements ErrorHandler {
300:
301: public boolean error = false;
302:
303: public void warning(SAXParseException exception)
304: throws SAXException {
305: }
306:
307: public void fatalError(SAXParseException exception)
308: throws SAXException {
309: error = true;
310: }
311:
312: public void error(SAXParseException exception)
313: throws SAXException {
314: error = true;
315: }
316: }
317: }
|