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: package org.netbeans.modules.collab.channel.output;
042:
043: import java.awt.Image;
044: import java.beans.*;
045: import java.io.*;
046: import java.util.*;
047: import javax.swing.*;
048:
049: import org.w3c.dom.*;
050: import org.apache.xmlbeans.*;
051: import org.openide.util.*;
052: import org.openide.windows.*;
053:
054: import com.sun.collablet.CollabMessage;
055: import com.sun.collablet.Conversation;
056: import com.sun.collablet.moxc.*;
057: import org.netbeans.modules.collab.core.Debug;
058: import org.netbeans.ns.shareOutput.x10.*;
059:
060: public class OutputCollablet extends MOXCCollablet {
061: ////////////////////////////////////////////////////////////////////////////
062: // Class variables
063: ////////////////////////////////////////////////////////////////////////////
064: private static int activeChannelCount;
065:
066: // private static final String OUTPUT_URI=
067: // "urn:com.sun.tools.ide.collab.channel.output/1";
068: private static final String OUTPUT_URI = "http://www.netbeans.org/ns/share-output/1_0"; // NOI18N
069:
070: // private static final String PREFIX="share-output"; // NOI18N
071: ////////////////////////////////////////////////////////////////////////////
072: // Instance variables
073: ////////////////////////////////////////////////////////////////////////////
074: private Conversation conversation;
075: private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
076: this );
077: private Map remoteOutputIOMap = new HashMap();
078:
079: /**
080: *
081: *
082: */
083: public OutputCollablet(Conversation conversation) {
084: super (conversation);
085: activeChannelCount++;
086: }
087:
088: /**
089: *
090: *
091: */
092: public String getDisplayName() {
093: return NbBundle.getMessage(OutputCollablet.class,
094: "LBL_OutputChannel_DisplayName");
095: }
096:
097: /**
098: *
099: *
100: */
101: public Icon getIcon() {
102: Image image = Utilities
103: .loadImage("org/netbeans/core/resources/frames/output.gif"); //NOI18N;
104:
105: if (image != null) {
106: return new ImageIcon(image);
107: }
108:
109: return null;
110: }
111:
112: /**
113: *
114: *
115: */
116: public void close() {
117: activeChannelCount--;
118:
119: // close remote output tabs
120: Set keys = remoteOutputIOMap.keySet();
121: Iterator it = keys.iterator();
122:
123: while (it.hasNext()) {
124: String key = (String) it.next();
125: ((InputOutput) remoteOutputIOMap.get(key))
126: .closeInputOutput();
127:
128: }
129: }
130:
131: ////////////////////////////////////////////////////////////////////////////
132: // Message handling methods
133: ////////////////////////////////////////////////////////////////////////////
134:
135: /**
136: *
137: *
138: */
139: public void shareAntOutput(String tabName, String id,
140: String contentString) {
141: try {
142: OpenDocument openDoc = OpenDocument.Factory.newInstance();
143: Open open = openDoc.addNewOpen();
144: Content content = open.addNewContent();
145: content.setContentType("plain/text");
146: content.setStringValue(Base64.encode(contentString
147: .getBytes()));
148: open.setInstance(id);
149: open.setName(Base64.encode(tabName.getBytes()));
150: open.setContent(content);
151:
152: HashMap suggestedPrefixes = new HashMap();
153:
154: // suggestedPrefixes.put(SOAP_URI, "soap"); // NOI18N
155: // suggestedPrefixes.put(MOXC_URI, "moxc"); // NOI18N
156: suggestedPrefixes.put(OUTPUT_URI, "share-output"); // NOI18N
157:
158: XmlOptions opts = new XmlOptions();
159: opts.setSavePrettyPrint();
160: opts.setSavePrettyPrintIndent(4);
161: opts.setCharacterEncoding("UTF-8"); // NOI18N
162: opts.setSaveSuggestedPrefixes(suggestedPrefixes);
163: opts.setSaveOuter();
164:
165: String xmlString = openDoc.xmlText(opts);
166:
167: String moxcMsg = constructMOXCMessage(xmlString);
168: String sendMsg = new String(moxcMsg.getBytes(), "UTF-8"); // NOI18N
169: CollabMessage collabMessage = getConversation()
170: .createMessage();
171: collabMessage.setContent(moxcMsg);
172: Debug.out.println(" send out xml msg: " + moxcMsg);
173:
174: // Set a header to ensure the chat channel doesn't pick this up
175: // collabMessage.setHeader("x-channel","not-chat"); // NOI18N
176: getConversation().sendMessage(collabMessage);
177: } catch (Exception e) {
178: Debug.debugNotify(e);
179: }
180: }
181:
182: /**
183: * construct soap message
184: *
185: */
186: private String constructMOXCMessage(String body) {
187: // temp, as moxc schema will change
188: StringBuffer buffer = new StringBuffer();
189:
190: buffer.append("<soap:Envelope xmlns:soap=");
191: buffer.append("\"");
192: buffer.append(MOXCConstants.SOAP_URI);
193: buffer.append("\" ");
194: buffer.append("xmlns:moxc=");
195: buffer.append("\"");
196: buffer.append(MOXCConstants.MOXC_URI);
197: buffer.append("\" ");
198: buffer.append(">");
199: buffer.append("<soap:Header>");
200: buffer.append("<moxc:message>");
201: buffer.append("<moxc:sender>");
202: buffer.append(getPrincipalID());
203: buffer.append("</moxc:sender>");
204: buffer.append("<moxc:conversation>");
205: buffer.append(getConversation().getIdentifier());
206: buffer.append("</moxc:conversation>");
207: buffer.append("<moxc:channel>");
208: buffer.append(OUTPUT_URI);
209: buffer.append("</moxc:channel>");
210: buffer.append("<moxc:instance>1</moxc:instance>");
211: buffer.append("</moxc:message></soap:Header><soap:Body>");
212: buffer.append(body);
213: buffer.append("</soap:Body></soap:Envelope>");
214:
215: return buffer.toString();
216: }
217:
218: /**
219: *
220: *
221: */
222: public String getPrincipalID() {
223: String principalId = getConversation().getCollabSession()
224: .getUserPrincipal().getIdentifier();
225:
226: if (principalId.indexOf("@") != -1) {
227: principalId = principalId.substring(0, principalId
228: .indexOf("@"));
229: }
230:
231: return principalId;
232: }
233:
234: /**
235: *
236: *
237: */
238: public void handleOpenOutput(String outputName, String instance_id,
239: String content) {
240: if (remoteOutputIOMap.get(instance_id) != null) {
241: try {
242: InputOutput io = (InputOutput) remoteOutputIOMap
243: .get(instance_id);
244: io.getOut().reset();
245: io.getOut().print(content);
246: io.getOut().flush();
247: io.select();
248: } catch (Exception e) {
249: Debug.debugNotify(e);
250: }
251: } else {
252: InputOutput inputOutput = IOProvider.getDefault().getIO(
253: outputName, true);
254: PrintWriter out = inputOutput.getOut();
255: out.print(content);
256: out.flush();
257:
258: remoteOutputIOMap.put(instance_id, inputOutput);
259: inputOutput.select();
260: }
261: }
262:
263: ////////////////////////////////////////////////////////////////////////////
264: // Property change support
265: ////////////////////////////////////////////////////////////////////////////
266:
267: /**
268: *
269: *
270: */
271: public void propertyChange(PropertyChangeEvent event) {
272: }
273:
274: /**
275: *
276: *
277: */
278: protected PropertyChangeSupport getChangeSupport() {
279: return changeSupport;
280: }
281:
282: /**
283: *
284: *
285: */
286: public void addPropertyChangeListener(
287: PropertyChangeListener listener) {
288: getChangeSupport().addPropertyChangeListener(listener);
289: }
290:
291: /**
292: *
293: *
294: */
295: public void removePropertyChangeListener(
296: PropertyChangeListener listener) {
297: getChangeSupport().removePropertyChangeListener(listener);
298: }
299:
300: ////////////////////////////////////////////////////////////////////////////
301: // Utility methods
302: ////////////////////////////////////////////////////////////////////////////
303:
304: /**
305: * Returns the number of active channels; used to determine if there is
306: * state that needs to be stored
307: *
308: */
309: protected static int getActiveChannelCount() {
310: return activeChannelCount;
311: }
312:
313: /**
314: * strip out html tag in tab name
315: *
316: */
317: private String getTabName(String name) {
318: String tabName = name;
319:
320: if (name.indexOf("<html>") != -1) // NOI18N
321: {
322: tabName = tabName.replaceAll("<html>", ""); // NOI18N
323: tabName = tabName.replaceAll("</html>", ""); // NOI18N
324: }
325:
326: if (name.indexOf("<b>") != -1) // NOI18N
327: {
328: tabName = tabName.replaceAll("<b>", ""); // NOI18N
329: tabName = tabName.replaceAll("</b>", ""); // NOI18N
330: }
331:
332: if (name.indexOf(" ") != -1) // NOI18N
333: {
334: tabName = tabName.replaceAll(" ", ""); // NOI18N
335: }
336:
337: return tabName;
338: }
339:
340: public String[] getNamespaces() {
341: String[] result = new String[1];
342: result[0] = OUTPUT_URI;
343:
344: return result;
345: }
346:
347: public boolean handleMOXCMessage(MOXCMessage message) {
348: try {
349: String sender = message.getSender();
350: Element element = message.getMessageElement();
351: OpenDocument openDoc = OpenDocument.Factory.parse(element);
352: Open open = openDoc.getOpen();
353: String tabName = open.getName();
354: Content content = open.getContent();
355:
356: String outputName = new String(Base64
357: .decode(open.getName()));
358: String outputContent = new String(Base64.decode(open
359: .getContent().getStringValue()));
360: String instance_id = open.getInstance();
361: outputName = outputName + " [" + sender + "]";
362:
363: handleOpenOutput(outputName, instance_id, outputContent);
364:
365: return true;
366: } catch (XmlException e) {
367: Debug.errorManager.notify(e);
368:
369: return false;
370: }
371: }
372: }
|