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.lib.ddl.impl;
043:
044: import java.io.Serializable;
045: import java.sql.Connection;
046: import java.sql.SQLException;
047: import java.sql.Statement;
048: import java.util.HashMap;
049: import java.util.Map;
050: import java.util.logging.Level;
051: import java.util.logging.Logger;
052:
053: import org.openide.DialogDisplayer;
054: import org.openide.NotifyDescriptor;
055: import org.openide.util.NbBundle;
056: import org.openide.windows.IOProvider;
057: import org.openide.windows.OutputWriter;
058:
059: import org.netbeans.lib.ddl.DatabaseSpecification;
060: import org.netbeans.lib.ddl.DDLCommand;
061: import org.netbeans.lib.ddl.DDLException;
062: import org.netbeans.lib.ddl.util.CommandFormatter;
063: import org.openide.windows.InputOutput;
064:
065: /**
066: * Basic implementation of DDLCommand. This class can be used for really simple
067: * commands with format and without arguments. Heavilly subclassed.
068: */
069: public class AbstractCommand implements Serializable, DDLCommand {
070: /** Command owner */
071: private DatabaseSpecification spec;
072:
073: /** Execution command with some exception */
074: boolean executionWithException;
075:
076: /** Command format */
077: private String format;
078:
079: /** Object owner and name */
080: private String owner, name;
081:
082: /** Additional properties */
083: private Map addprops;
084:
085: static final long serialVersionUID = -560515030304320086L;
086:
087: private String quoteStr;
088:
089: /** Indicates if the object is being newly created or is an existing object */
090: private boolean newObject = false;
091:
092: /** Returns specification (DatabaseSpecification) for this command */
093: public DatabaseSpecification getSpecification() {
094: return spec;
095: }
096:
097: /**
098: * Sets specification (DatabaseSpecification) for this command. This method is usually called
099: * in relevant createXXX method.
100: * @param specification New specification object.
101: */
102: public void setSpecification(DatabaseSpecification specification) {
103: spec = specification;
104: }
105:
106: /**
107: * Sets format for this command. This method is usually called in relevant createXXX
108: * method.
109: * @param fmt New format.
110: */
111: public void setFormat(String fmt) {
112: format = fmt;
113: }
114:
115: /** Returns name of modified object */
116: public String getObjectName() {
117: return name;
118: }
119:
120: /** Sets name to be used in command
121: * @param nam New name.
122: */
123: public void setObjectName(String nam) {
124: name = nam;
125: }
126:
127: /** Returns name of modified object */
128: public String getObjectOwner() {
129: if (owner != null)
130: if (owner.trim().equals(""))
131: setObjectOwner(null);
132:
133: return owner;
134: }
135:
136: /** Sets name to be used in command
137: * @param objectowner New owner.
138: */
139: public void setObjectOwner(String objectowner) {
140: owner = objectowner;
141: }
142:
143: public boolean isNewObject() {
144: return newObject;
145: }
146:
147: public void setNewObject(boolean newObject) {
148: this .newObject = newObject;
149: }
150:
151: /** Returns general property */
152: public Object getProperty(String pname) {
153: return addprops.get(pname);
154: }
155:
156: /** Sets general property */
157: public void setProperty(String pname, Object pval) {
158: if (addprops == null)
159: addprops = new HashMap();
160: addprops.put(pname, pval);
161: }
162:
163: /**
164: * Returns properties and it's values supported by this object.
165: * object.name Name of the object; use setObjectName()
166: * object.owner Name of the object; use setObjectOwner()
167: * Throws DDLException if object name is not specified.
168: */
169: public Map getCommandProperties() throws DDLException {
170: HashMap args = new HashMap();
171: if (addprops != null)
172: args.putAll(addprops);
173: String oname = getObjectName();
174: if (oname != null)
175: args.put("object.name", newObject ? getObjectName()
176: : quote(getObjectName())); // NOI18N
177: else
178: throw new DDLException(NbBundle.getBundle(
179: "org.netbeans.lib.ddl.resources.Bundle").getString(
180: "EXC_Unknown")); // NOI18N
181: args.put("object.owner", quote(getObjectOwner())); // NOI18N
182:
183: return args;
184: }
185:
186: /**
187: * Executes command.
188: * First it calls getCommand() to obtain command text. Then tries to open JDBC
189: * connection and execute it. If connection is already open, uses it and leave
190: * open; otherwise creates new one and closes after use. Throws DDLException if
191: * something wrong occurs.
192: */
193: public void execute() throws DDLException {
194: String fcmd;
195: Connection fcon = null;
196: boolean opened = false;
197: executionWithException = false;
198:
199: try {
200: fcmd = getCommand();
201: } catch (Exception e) {
202: Logger.getLogger("global").log(Level.INFO, null, e);
203: executionWithException = true;
204: DialogDisplayer.getDefault().notify(
205: new NotifyDescriptor.Message(NbBundle.getBundle(
206: "org.netbeans.lib.ddl.resources.Bundle")
207: .getString("EXC_UnableToFormat")
208: + "\n" + format + "\n" + e.getMessage(),
209: NotifyDescriptor.ERROR_MESSAGE)); // NOI18N
210: return;
211: }
212:
213: //In case of debug mode print command
214: if (spec.getSpecificationFactory().isDebugMode()) {
215:
216: try {
217: InputOutput io = IOProvider
218: .getDefault()
219: .getIO(
220: NbBundle
221: .getBundle(
222: "org.netbeans.lib.ddl.resources.Bundle")
223: .getString("LBL_Output_Window"),
224: false);
225: io.select();
226: OutputWriter ow = io.getOut(); //NOI18N
227: if (ow != null) {
228: ow.println(fcmd);
229: ow.println(" "); //NOI18N
230: } else
231: throw new Exception();
232:
233: } catch (Exception e) {
234: Logger.getLogger("global").log(Level.INFO,
235: e.getMessage() + "\n" + fcmd); //NOI18N
236: }
237: }
238:
239: try {
240: fcon = spec.getJDBCConnection();
241: if (fcon == null) {
242: fcon = spec.openJDBCConnection();
243: opened = true;
244: }
245:
246: Statement stat = fcon.createStatement();
247: stat.execute(fcmd);
248: stat.close();
249: } catch (Exception e) {
250: executionWithException = true;
251: if (opened && fcon != null)
252: spec.closeJDBCConnection();
253:
254: throw new DDLException(NbBundle.getBundle(
255: "org.netbeans.lib.ddl.resources.Bundle").getString(
256: "EXC_UnableToExecute")
257: + "\n" + fcmd + "\n" + e.getMessage()); // NOI18N
258: }
259:
260: if (opened)
261: spec.closeJDBCConnection();
262: }
263:
264: /**
265: * Returns full string representation of command. This string needs no
266: * formatting and could be used directly as argument of executeUpdate()
267: * command. Throws DDLException if format is not specified or CommandFormatter
268: * can't format it (it uses MapFormat to process entire lines and can solve []
269: * enclosed expressions as optional.
270: */
271: public String getCommand() throws DDLException {
272: if (format == null)
273: throw new DDLException(NbBundle.getBundle(
274: "org.netbeans.lib.ddl.resources.Bundle").getString(
275: "EXC_NoFormatSpec")); // NOI18N
276: try {
277: Map props = getCommandProperties();
278: return CommandFormatter.format(format, props);
279: } catch (Exception e) {
280: throw new DDLException(e.getMessage());
281: }
282: }
283:
284: /** information about appearance some exception in the last execute a bunch of commands */
285: public boolean wasException() {
286: return executionWithException;
287: }
288:
289: private String getQuoteString() {
290: try {
291: quoteStr = getSpecification().getJDBCConnection()
292: .getMetaData().getIdentifierQuoteString();
293:
294: //Firebird patch (commands don't work with quoted names)
295: if (getSpecification().getJDBCConnection().getMetaData()
296: .getDatabaseProductName().indexOf("Firebird") != -1) //NOI18N
297: quoteStr = "";
298: } catch (SQLException exc) {
299: //PENDING
300: }
301: if (quoteStr == null)
302: quoteStr = ""; //NOI18N
303: else
304: quoteStr.trim();
305:
306: return quoteStr;
307: }
308:
309: public String quote(String name) {
310: if (name == null || name.equals(""))
311: return name;
312:
313: if (quoteStr == null)
314: quoteStr = getQuoteString();
315:
316: return quoteStr + name + quoteStr;
317: }
318:
319: /** Reads object from stream */
320: public void readObject(java.io.ObjectInputStream in)
321: throws java.io.IOException, ClassNotFoundException {
322: format = (String) in.readObject();
323: owner = (String) in.readObject();
324: name = (String) in.readObject();
325: addprops = (Map) in.readObject();
326: }
327:
328: /** Writes object to stream */
329: public void writeObject(java.io.ObjectOutputStream out)
330: throws java.io.IOException {
331: //System.out.println("Writing command "+name);
332: out.writeObject(format);
333: out.writeObject(owner);
334: out.writeObject(name);
335: out.writeObject(addprops);
336: }
337: }
|