1 19 20 package org.netbeans.modules.j2ee.ddloaders.common.xmlutils; 21 22 import java.awt.Dialog ; 23 import java.io.BufferedReader ; 24 import java.io.BufferedWriter ; 25 import java.io.ByteArrayOutputStream ; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.io.InputStreamReader ; 29 import java.io.OutputStream ; 30 import java.io.OutputStreamWriter ; 31 import java.io.Reader ; 32 import java.io.UnsupportedEncodingException ; 33 import java.io.Writer ; 34 import java.nio.charset.Charset ; 35 import java.nio.charset.CharsetEncoder ; 36 import javax.swing.text.BadLocationException ; 37 import javax.swing.text.EditorKit ; 38 import javax.swing.text.StyledDocument ; 39 40 import org.netbeans.modules.xml.api.EncodingUtil; 41 import org.openide.DialogDescriptor; 42 import org.openide.DialogDisplayer; 43 import org.openide.ErrorManager; 44 import org.openide.NotifyDescriptor; 45 import org.openide.awt.StatusDisplayer; 46 import org.openide.awt.UndoRedo; 47 import org.openide.cookies.CloseCookie; 48 import org.openide.cookies.EditCookie; 49 import org.openide.cookies.EditorCookie; 50 import org.openide.cookies.LineCookie; 51 import org.openide.cookies.PrintCookie; 52 import org.openide.cookies.SaveCookie; 53 import org.openide.filesystems.FileLock; 54 import org.openide.filesystems.FileObject; 55 import org.openide.text.DataEditorSupport; 56 import org.openide.text.NbDocument; 57 import org.openide.util.NbBundle; 58 import org.openide.util.RequestProcessor; 59 import org.openide.windows.CloneableOpenSupport; 60 61 65 public class XMLJ2eeEditorSupport extends DataEditorSupport 66 implements EditCookie, EditorCookie.Observable,LineCookie, CloseCookie, PrintCookie { 67 68 69 private static final int AUTO_PARSING_DELAY = 2000; 70 private DialogDescriptor dialog; 71 private RequestProcessor.Task parsingDocumentTask; 72 XMLJ2eeDataObject dataObject; 73 74 77 public XMLJ2eeEditorSupport(XMLJ2eeDataObject obj) { 78 super (obj, new XmlEnv (obj)); 79 dataObject=obj; 80 81 setMIMEType ("text/xml"); } 84 85 88 protected void saveFromKitToStream (StyledDocument doc, EditorKit kit, 89 OutputStream stream) 90 throws IOException , BadLocationException { 91 EditorKit k = this.createEditorKit(); 94 OutputStreamWriter osw = new OutputStreamWriter (stream, "UTF8"); Writer writer = new BufferedWriter (osw); 96 k.write(writer, doc, 0, doc.getLength()); 97 writer.close(); 98 } 99 100 103 protected void loadFromStreamToKit (StyledDocument doc, InputStream stream, 104 EditorKit kit) 105 throws IOException , BadLocationException { 106 EditorKit k = this.createEditorKit(); 109 InputStreamReader isr = new InputStreamReader (stream, "UTF8"); Reader reader = new BufferedReader (isr); 111 k.read(reader, doc, 0); 112 reader.close(); 113 } 114 115 118 public void restartTimer() { 119 dataObject.setDocumentDirty(true); 121 Runnable r = new Runnable () { 122 public void run() { 123 dataObject.parsingDocument(); 124 } 125 }; 126 if (parsingDocumentTask==null || parsingDocumentTask.isFinished() || 127 parsingDocumentTask.cancel()) { 128 parsingDocumentTask = RequestProcessor.getDefault().post(r,100); 129 } else { 130 parsingDocumentTask = RequestProcessor.getDefault().post(r,AUTO_PARSING_DELAY); 131 } 132 } 133 134 138 protected boolean notifyModified () { 139 boolean notif = super.notifyModified(); 140 if (!notif){ 141 return false; 142 } 143 XMLJ2eeDataObject obj = (XMLJ2eeDataObject) getDataObject (); 144 if (obj.getCookie (SaveCookie.class) == null) { 146 obj.addSaveCookie (new Save ()); 147 } 148 if (!obj.isNodeDirty()) restartTimer(); 149 return true; 150 } 151 152 155 protected void notifyUnmodified () { 156 super.notifyUnmodified (); 157 XMLJ2eeDataObject obj = (XMLJ2eeDataObject) getDataObject (); 158 obj.removeSaveCookie(); 159 } 160 161 164 private class Save implements SaveCookie { 165 166 public void save () throws IOException { 167 XMLJ2eeDataObject obj = (XMLJ2eeDataObject) getDataObject (); 168 if (obj.isDocumentValid()) { 169 obj.setSavingDocument(true); 170 saveDocument(); 171 }else { 172 obj.displayErrorMessage(); 173 dialog = new DialogDescriptor( 174 NbBundle.getMessage (XMLJ2eeEditorSupport.class, "MSG_invalidXmlWarning"), 175 NbBundle.getMessage (XMLJ2eeEditorSupport.class, "TTL_invalidXmlWarning")); 176 Dialog d = DialogDisplayer.getDefault().createDialog(dialog); 177 d.setVisible(true); 178 if (dialog.getValue() == DialogDescriptor.OK_OPTION) { 179 obj.setSavingDocument(true); 180 saveDocument(); 181 } 182 } 183 } 184 } 185 189 public void saveDocument () throws IOException { 190 final StyledDocument doc = getDocument(); 191 String enc = EncodingUtil.detectEncoding(doc); 193 if (enc == null) enc = "UTF8"; 195 try { 196 new OutputStreamWriter (new ByteArrayOutputStream (1), enc); 198 if (!checkCharsetConversion(enc)) { 199 return; 200 } 201 super.saveDocument(); 202 getDataObject().setModified (false); 204 } catch (UnsupportedEncodingException ex) { 205 String message = NbBundle.getMessage(XMLJ2eeEditorSupport.class,"TEXT_SAVE_AS_UTF", enc); 207 NotifyDescriptor descriptor = new NotifyDescriptor.Confirmation(message); 208 Object res = DialogDisplayer.getDefault().notify(descriptor); 209 210 if (res.equals(NotifyDescriptor.YES_OPTION)) { 211 212 214 try { 215 final int MAX_PROLOG = 1000; 216 int maxPrologLen = Math.min(MAX_PROLOG, doc.getLength()); 217 final char prolog[] = doc.getText(0, maxPrologLen).toCharArray(); 218 int prologLen = 0; 220 if (prolog[0] == '<' && prolog[1] == '?' && prolog[2] == 'x') { 222 223 for (int i = 3; i<maxPrologLen; i++) { 225 if (prolog[i] == '?' && prolog[i+1] == '>') { 226 prologLen = i + 1; 227 break; 228 } 229 } 230 } 231 232 final int passPrologLen = prologLen; 233 234 Runnable edit = new Runnable () { 235 public void run() { 236 try { 237 238 doc.remove(0, passPrologLen + 1); doc.insertString(0, "<?xml version='1.0' encoding='UTF-8' ?> \n<!-- was: " + new String (prolog, 0, passPrologLen + 1) + " -->", null); 241 } catch (BadLocationException e) { 242 if (System.getProperty("netbeans.debug.exceptions") != null) e.printStackTrace(); 244 } 245 } 246 }; 247 248 NbDocument.runAtomic(doc, edit); 249 250 super.saveDocument(); 251 getDataObject().setModified (false); 253 254 } catch (BadLocationException lex) { 255 ErrorManager.getDefault().notify(lex); 256 } 257 258 } else { return; 260 } 261 } 262 } 263 264 private boolean checkCharsetConversion(final String encoding) { 265 boolean value = true; 266 try { 267 CharsetEncoder coder = Charset.forName(encoding).newEncoder(); 268 if (!coder.canEncode(getDocument().getText(0, getDocument().getLength()))){ 269 NotifyDescriptor nd = new NotifyDescriptor.Confirmation( 270 NbBundle.getMessage(XMLJ2eeEditorSupport.class, "MSG_BadCharConversion", 271 new Object [] { getDataObject().getPrimaryFile().getNameExt(), 272 encoding}), 273 NotifyDescriptor.YES_NO_OPTION, 274 NotifyDescriptor.WARNING_MESSAGE); 275 nd.setValue(NotifyDescriptor.NO_OPTION); 276 DialogDisplayer.getDefault().notify(nd); 277 if(nd.getValue() != NotifyDescriptor.YES_OPTION) { 278 value = false; 279 } 280 } 281 } catch (BadLocationException e){ 282 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 283 } 284 return value; 285 } 286 287 public UndoRedo.Manager getUndo(){ 288 return getUndoRedo(); 289 } 290 291 295 protected String messageName () { 296 String name = super.messageName(); 297 int index1 = name.indexOf('['); 298 299 if (index1>=0) { 300 String prefix = name.substring(0,index1); 301 int index2 = name.lastIndexOf(']'); 302 String postfix=""; 303 if (index2>=0) postfix = name.substring(index2+1); 304 return prefix+postfix; 305 } 306 return name; 307 } 308 309 313 private static class XmlEnv extends DataEditorSupport.Env { 314 315 private static final long serialVersionUID = -800036748848958489L; 316 317 319 322 public XmlEnv (XMLJ2eeDataObject obj) { 323 super (obj); 324 } 325 326 329 protected FileObject getFile () { 330 return getDataObject ().getPrimaryFile (); 331 } 332 333 339 protected FileLock takeLock () throws IOException { 340 return ((XMLJ2eeDataObject) getDataObject ()).getPrimaryEntry ().takeLock (); 341 } 342 343 348 public CloneableOpenSupport findCloneableOpenSupport () { 349 return (XMLJ2eeEditorSupport) getDataObject ().getCookie (XMLJ2eeEditorSupport.class); 350 } 351 } 352 } 353 | Popular Tags |