1 19 20 package org.netbeans.modules.web.struts; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import javax.swing.event.DocumentEvent ; 25 import javax.swing.event.DocumentListener ; 26 import javax.swing.text.BadLocationException ; 27 import org.netbeans.modules.xml.api.EncodingUtil; 28 import org.openide.DialogDescriptor; 29 import org.openide.DialogDisplayer; 30 import org.openide.ErrorManager; 31 import org.openide.NotifyDescriptor; 32 import org.openide.filesystems.FileLock; 33 import org.openide.filesystems.FileObject; 34 import org.openide.nodes.Node.Cookie; 35 import org.openide.text.DataEditorSupport; 36 import org.openide.cookies.*; 37 import org.openide.text.NbDocument; 38 import org.openide.util.NbBundle; 39 import org.openide.util.RequestProcessor; 40 41 45 public class StrutsConfigEditorSupport extends DataEditorSupport 46 implements OpenCookie, EditCookie, EditorCookie.Observable, PrintCookie, CloseCookie { 47 48 50 private final SaveCookie saveCookie = new SaveCookie() { 51 52 public void save() throws java.io.IOException { 53 StrutsConfigDataObject obj = (StrutsConfigDataObject) getDataObject (); 54 restartTimer(); 56 obj.parsingDocument(); 57 if (obj.isDocumentValid()) { 58 saveDocument(); 59 }else { 60 DialogDescriptor dialog = new DialogDescriptor( 61 NbBundle.getMessage (StrutsConfigEditorSupport.class, "MSG_invalidXmlWarning"), NbBundle.getMessage (StrutsConfigEditorSupport.class, "TTL_invalidXmlWarning")); java.awt.Dialog d = org.openide.DialogDisplayer.getDefault().createDialog(dialog); 64 d.setVisible(true); 65 if (dialog.getValue() == org.openide.DialogDescriptor.OK_OPTION) { 66 saveDocument(); 67 } 68 } 69 } 70 }; 71 72 private StrutsConfigDataObject dataObject; 73 private RequestProcessor.Task parsingDocumentTask; 74 75 private static final int AUTO_PARSING_DELAY = 2000; 76 77 public StrutsConfigEditorSupport(StrutsConfigDataObject dobj) { 78 super(dobj,new XmlEnv(dobj)); 79 setMIMEType("text/x-struts+xml"); dataObject = dobj; 81 initialize(); 83 } 84 85 private void initialize() { 86 final DocumentListener docListener = new DocumentListener () { 88 public void insertUpdate(DocumentEvent e) { change(e); } 89 public void changedUpdate(DocumentEvent e) { } 90 public void removeUpdate(DocumentEvent e) { change(e); } 91 92 private void change(DocumentEvent e) { 93 if (!dataObject.isNodeDirty()) restartTimer(); 94 } 95 }; 96 97 addPropertyChangeListener(new PropertyChangeListener () { 99 public void propertyChange(PropertyChangeEvent evt) { 100 if (EditorCookie.Observable.PROP_DOCUMENT.equals(evt.getPropertyName()) 101 && isDocumentLoaded() && getDocument() != null) { 102 getDocument().addDocumentListener(docListener); 103 } 104 } 105 }); 106 } 107 108 112 public void saveDocument () throws java.io.IOException { 113 final javax.swing.text.StyledDocument doc = getDocument(); 114 String defaultEncoding = "UTF-8"; String enc = EncodingUtil.detectEncoding(doc); 117 boolean changeEncodingToDefault = false; 118 if (enc == null) enc = defaultEncoding; 119 120 if (!isSupportedEncoding(enc)){ 122 NotifyDescriptor nd = new NotifyDescriptor.Confirmation( 123 NbBundle.getMessage (StrutsConfigEditorSupport.class, "MSG_BadEncodingDuringSave", new Object [] { getDataObject().getPrimaryFile().getNameExt(), 125 enc, 126 defaultEncoding} ), 127 NotifyDescriptor.YES_NO_OPTION, 128 NotifyDescriptor.WARNING_MESSAGE); 129 nd.setValue(NotifyDescriptor.NO_OPTION); 130 DialogDisplayer.getDefault().notify(nd); 131 if(nd.getValue() != NotifyDescriptor.YES_OPTION) return; 132 changeEncodingToDefault = true; 133 } 134 135 if (!changeEncodingToDefault){ 136 try { 138 java.nio.charset.CharsetEncoder coder = java.nio.charset.Charset.forName(enc).newEncoder(); 139 if (!coder.canEncode(doc.getText(0, doc.getLength()))){ 140 NotifyDescriptor nd = new NotifyDescriptor.Confirmation( 141 NbBundle.getMessage (StrutsConfigEditorSupport.class, "MSG_BadCharConversion", new Object [] { getDataObject().getPrimaryFile().getNameExt(), 143 enc}), 144 NotifyDescriptor.YES_NO_OPTION, 145 NotifyDescriptor.WARNING_MESSAGE); 146 nd.setValue(NotifyDescriptor.NO_OPTION); 147 DialogDisplayer.getDefault().notify(nd); 148 if(nd.getValue() != NotifyDescriptor.YES_OPTION) return; 149 } 150 } 151 catch (javax.swing.text.BadLocationException e){ 152 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 153 } 154 super.saveDocument(); 155 getDataObject().setModified (false); 157 } 158 else { 159 161 try { 162 final int MAX_PROLOG = 1000; 163 int maxPrologLen = Math.min(MAX_PROLOG, doc.getLength()); 164 final char prolog[] = doc.getText(0, maxPrologLen).toCharArray(); 165 int prologLen = 0; 167 if (prolog[0] == '<' && prolog[1] == '?' && prolog[2] == 'x') { 169 170 for (int i = 3; i<maxPrologLen; i++) { 172 if (prolog[i] == '?' && prolog[i+1] == '>') { 173 prologLen = i + 1; 174 break; 175 } 176 } 177 } 178 179 final int passPrologLen = prologLen; 180 181 Runnable edit = new Runnable () { 182 public void run() { 183 try { 184 185 doc.remove(0, passPrologLen + 1); doc.insertString(0, "<?xml version='1.0' encoding='UTF-8' ?> \n<!-- was: " + new String (prolog, 0, passPrologLen + 1) + " -->", null); 188 } catch (BadLocationException e) { 189 if (System.getProperty("netbeans.debug.exceptions") != null) e.printStackTrace(); 191 } 192 } 193 }; 194 195 NbDocument.runAtomic(doc, edit); 196 197 super.saveDocument(); 198 getDataObject().setModified (false); 200 } 201 catch (javax.swing.text.BadLocationException e){ 202 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 203 } 204 } 205 } 206 207 private boolean isSupportedEncoding(String encoding){ 208 boolean supported; 209 try{ 210 supported = java.nio.charset.Charset.isSupported(encoding); 211 } 212 catch (java.nio.charset.IllegalCharsetNameException e){ 213 supported = false; 214 } 215 216 return supported; 217 } 218 219 222 public void restartTimer() { 223 if (parsingDocumentTask==null || parsingDocumentTask.isFinished() || 224 parsingDocumentTask.cancel()) { 225 dataObject.setDocumentDirty(true); 226 Runnable r = new Runnable () { 227 public void run() { 228 dataObject.parsingDocument(); 229 } 230 }; 231 if (parsingDocumentTask != null) 232 parsingDocumentTask = RequestProcessor.getDefault().post(r, AUTO_PARSING_DELAY); 233 else 234 parsingDocumentTask = RequestProcessor.getDefault().post(r, 100); 235 } 236 } 237 238 243 protected boolean notifyModified () { 244 if (!super.notifyModified()) 245 return false; 246 247 addSaveCookie(); 248 249 return true; 250 } 251 252 253 protected void notifyUnmodified () { 254 super.notifyUnmodified(); 255 256 removeSaveCookie(); 257 } 258 259 260 private void addSaveCookie() { 261 StrutsConfigDataObject obj = (StrutsConfigDataObject)getDataObject(); 262 263 if(obj.getCookie(SaveCookie.class) == null) { 265 obj.getCookieSet0().add(saveCookie); 266 obj.setModified(true); 267 } 268 } 269 270 271 private void removeSaveCookie() { 272 StrutsConfigDataObject obj = (StrutsConfigDataObject)getDataObject(); 273 274 Cookie cookie = obj.getCookie(SaveCookie.class); 276 277 if(cookie != null && cookie.equals(saveCookie)) { 278 obj.getCookieSet0().remove(saveCookie); 279 obj.setModified(false); 280 } 281 } 282 283 287 private static class XmlEnv extends DataEditorSupport.Env { 288 289 private static final long serialVersionUID = -800036748848958489L; 290 291 293 296 public XmlEnv (StrutsConfigDataObject obj) { 297 super (obj); 298 } 299 300 303 protected FileObject getFile () { 304 return getDataObject ().getPrimaryFile (); 305 } 306 307 313 protected FileLock takeLock () throws java.io.IOException { 314 return ((StrutsConfigDataObject) getDataObject ()).getPrimaryEntry ().takeLock (); 315 } 316 317 322 public org.openide.windows.CloneableOpenSupport findCloneableOpenSupport () { 323 return (StrutsConfigEditorSupport) getDataObject ().getCookie (StrutsConfigEditorSupport.class); 324 } 325 } 326 } 327 | Popular Tags |