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: package org.netbeans.modules.j2ee.jboss4.config.mdb;
043:
044: import java.io.BufferedOutputStream;
045: import java.io.File;
046: import java.io.IOException;
047: import java.io.OutputStream;
048: import java.util.HashSet;
049: import java.util.Set;
050: import org.netbeans.modules.j2ee.deployment.common.api.ConfigurationException;
051: import org.netbeans.modules.j2ee.deployment.common.api.MessageDestination;
052: import org.netbeans.modules.j2ee.deployment.plugins.api.InstanceProperties;
053: import org.netbeans.modules.j2ee.deployment.plugins.spi.MessageDestinationDeployment;
054: import org.netbeans.modules.j2ee.jboss4.ide.ui.JBPluginProperties;
055: import org.netbeans.modules.schema2beans.BaseBean;
056: import org.openide.filesystems.FileLock;
057: import org.openide.filesystems.FileObject;
058: import org.openide.filesystems.FileSystem;
059: import org.openide.filesystems.FileUtil;
060:
061: /**
062: *
063: * @author Libor Kotouc
064: */
065: public final class JBossMessageDestinationDeployment implements
066: MessageDestinationDeployment {
067:
068: // private static final String DSdotXML = "-ds.xml"; // NOI18N
069: // private static final String JBossDSdotXML = "jboss-ds.xml"; // NOI18N
070:
071: // server's deploy dir
072: private FileObject deployDir;
073:
074: public JBossMessageDestinationDeployment(String serverUrl) {
075: String serverDirPath = InstanceProperties
076: .getInstanceProperties(serverUrl).getProperty(
077: JBPluginProperties.PROPERTY_DEPLOY_DIR);
078: deployDir = FileUtil.toFileObject(new File(serverDirPath));
079: }
080:
081: public Set<MessageDestination> getMessageDestinations()
082: throws ConfigurationException {
083: HashSet<MessageDestination> destinations = new HashSet<MessageDestination>();
084: destinations.add(new JBossMessageDestination(
085: "SampleServerQueue", MessageDestination.Type.QUEUE));
086: destinations.add(new JBossMessageDestination(
087: "SampleServerTopic", MessageDestination.Type.TOPIC));
088: return destinations;
089: }
090:
091: public void deployMessageDestinations(
092: Set<MessageDestination> destinations)
093: throws ConfigurationException {
094: }
095:
096: /*
097: public Set<Datasource> getDatasources() throws ConfigurationException {
098:
099: Set<Datasource> datasources = new HashSet<Datasource>();
100:
101: if (deployDir == null || !deployDir.isValid() || !deployDir.isFolder() || !deployDir.canRead()) {
102: ErrorManager.getDefault().log(ErrorManager.USER,
103: NbBundle.getMessage(JBossMessageDestinationDeployment.class, "ERR_WRONG_DEPLOY_DIR"));
104: return datasources;
105: }
106:
107: Enumeration files = deployDir.getChildren(true);
108: List<FileObject> confs = new LinkedList<FileObject>();
109: while (files.hasMoreElements()) { // searching for config files with DS
110: FileObject file = (FileObject) files.nextElement();
111: if (!file.isFolder() && file.getNameExt().endsWith(DSdotXML) && file.canRead())
112: confs.add(file);
113: }
114:
115: if (confs.size() == 0) // nowhere to search
116: return datasources;
117:
118: for (Iterator it = confs.iterator(); it.hasNext();) {
119: FileObject dsFO = (FileObject)it.next();
120: File dsFile = FileUtil.toFile(dsFO);
121: try {
122: Datasources ds = null;
123: try {
124: ds = Datasources.createGraph(dsFile);
125: } catch (RuntimeException re) {
126: // most likely not a data source (e.g. jms-ds.xml in JBoss 5.x)
127: String msg = NbBundle.getMessage(JBossMessageDestinationDeployment.class, "MSG_NotParseableDatasources", dsFile.getAbsolutePath());
128: ErrorManager.getDefault().log(ErrorManager.INFORMATIONAL, msg);
129: continue;
130: }
131: LocalTxDatasource ltxds[] = ds.getLocalTxDatasource();
132: for (int i = 0; i < ltxds.length; i++) {
133: if (ltxds[i].getJndiName().length() > 0) {
134: datasources.add(new JBossDatasource(
135: ltxds[i].getJndiName(),
136: ltxds[i].getConnectionUrl(),
137: ltxds[i].getUserName(),
138: ltxds[i].getPassword(),
139: ltxds[i].getDriverClass()));
140: }
141: }
142: } catch (IOException ioe) {
143: String msg = NbBundle.getMessage(JBossMessageDestinationDeployment.class, "MSG_CannotReadDatasources", dsFile.getAbsolutePath());
144: throw new ConfigurationException(msg, ioe);
145: } catch (RuntimeException re) {
146: String msg = NbBundle.getMessage(JBossMessageDestinationDeployment.class, "MSG_NotParseableDatasources", dsFile.getAbsolutePath());
147: throw new ConfigurationException(msg ,re);
148: }
149: }
150:
151: return datasources;
152: }
153:
154: public void deployDatasources(Set<Datasource> datasources)
155: throws ConfigurationException, DatasourceAlreadyExistsException
156: {
157: Set<Datasource> deployedDS = getDatasources();
158: Map<String, Datasource> ddsMap = transform(deployedDS); // for faster searching
159:
160: HashMap<String, Datasource> newDS = new HashMap<String, Datasource>(); // will contain all ds which do not conflict with existing ones
161:
162: //resolve all conflicts
163: LinkedList<Datasource> conflictDS = new LinkedList<Datasource>();
164: for (Iterator<Datasource> it = datasources.iterator(); it.hasNext();) {
165: Object o = it.next();
166: if (!(o instanceof JBossDatasource))
167: continue;
168: JBossDatasource ds = (JBossDatasource)o;
169: String jndiName = ds.getJndiName();
170: if (ddsMap.keySet().contains(jndiName)) { // conflicting ds found
171: if (!ddsMap.get(jndiName).equals(ds)) { // found ds is not equal
172: conflictDS.add(ddsMap.get(jndiName)); // NOI18N
173: }
174: }
175: else if (jndiName != null) {
176: newDS.put(jndiName, ds);
177: }
178: }
179:
180: if (conflictDS.size() > 0) { // conflict found -> exception
181: throw new DatasourceAlreadyExistsException(conflictDS);
182: }
183:
184: //write jboss-ds.xml
185: FileObject dsXmlFo = serverDir.getFileObject(JBossDSdotXML);
186: File dsXMLFile = (dsXmlFo != null ? FileUtil.toFile(dsXmlFo) : null);
187:
188: Datasources deployedDSGraph = null;
189: try {
190: deployedDSGraph = (dsXMLFile != null ? Datasources.createGraph(dsXMLFile) : new Datasources());
191: }
192: catch (IOException ioe) {
193: ErrorManager.getDefault().annotate(ioe, NbBundle.getMessage(getClass(), "ERR_CannotReadDSdotXml"));
194: ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioe);
195: return;
196: }
197:
198: //merge ds graph with newDS - remove conflicting ds from graph
199: LocalTxDatasource ltxds[] = deployedDSGraph.getLocalTxDatasource();
200: for (int i = 0; i < ltxds.length; i++) {
201: String jndiName = ltxds[i].getJndiName();
202: if (newDS.keySet().contains(jndiName)) //conflict, we must remove it from graph
203: deployedDSGraph.removeLocalTxDatasource(ltxds[i]);
204: }
205:
206: //add all ds from newDS
207: for (Iterator it = newDS.values().iterator(); it.hasNext();) {
208: JBossDatasource ds = (JBossDatasource) it.next();
209:
210: LocalTxDatasource lds = new LocalTxDatasource();
211: lds.setJndiName(ds.getJndiName());
212: lds.setConnectionUrl(ds.getUrl());
213: lds.setDriverClass(ds.getDriverClassName());
214: lds.setUserName(ds.getUsername());
215: lds.setPassword(ds.getPassword());
216: lds.setMinPoolSize(ds.getMinPoolSize());
217: lds.setMaxPoolSize(ds.getMaxPoolSize());
218: lds.setIdleTimeoutMinutes(ds.getIdleTimeoutMinutes());
219:
220: deployedDSGraph.addLocalTxDatasource(lds);
221: }
222:
223: //write modified graph into jboss-ds.xml
224: if (newDS.size() > 0) {
225: if (dsXMLFile == null) {
226: try {
227: dsXmlFo = serverDir.createData(JBossDSdotXML);
228: }
229: catch (IOException ioe) {
230: ErrorManager.getDefault().annotate(ioe, NbBundle.getMessage(getClass(), "ERR_CannotCreateDSdotXml"));
231: ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ioe);
232: return;
233: }
234:
235: dsXMLFile = FileUtil.toFile(dsXmlFo);
236: }
237:
238: writeFile(dsXMLFile, deployedDSGraph);
239: }
240:
241: }
242:
243: private Map<String, Datasource> transform(Set<Datasource> datasources) {
244: HashMap<String, Datasource> map = new HashMap<String, Datasource>();
245: for (Iterator it = datasources.iterator(); it.hasNext();) {
246: JBossDatasource ds = (JBossDatasource) it.next();
247: if (ds.getJndiName() != null)
248: map.put(ds.getJndiName(), ds);
249: }
250: return map;
251: }
252: */
253: private void writeFile(final File file, final BaseBean bean)
254: throws ConfigurationException {
255: try {
256:
257: FileSystem fs = deployDir.getFileSystem();
258: fs.runAtomicAction(new FileSystem.AtomicAction() {
259: public void run() throws IOException {
260: OutputStream os = null;
261: FileLock lock = null;
262: try {
263: String name = file.getName();
264: FileObject configFO = deployDir
265: .getFileObject(name);
266: if (configFO == null) {
267: configFO = deployDir.createData(name);
268: }
269: lock = configFO.lock();
270: os = new BufferedOutputStream(configFO
271: .getOutputStream(lock), 4096);
272: // TODO notification needed
273: if (bean != null) {
274: bean.write(os);
275: }
276: } finally {
277: if (os != null) {
278: try {
279: os.close();
280: } catch (IOException ioe) {
281: }
282: }
283: if (lock != null)
284: lock.releaseLock();
285: }
286: }
287: });
288: } catch (IOException e) {
289: throw new ConfigurationException(e.getLocalizedMessage());
290: }
291: }
292:
293: }
|