1 19 20 package org.netbeans.modules.web.core.jsploader; 21 22 import java.lang.ref.WeakReference ; 23 import java.lang.ref.SoftReference ; 24 import java.util.*; 25 import javax.swing.SwingUtilities ; 26 import org.netbeans.modules.web.core.jsploader.api.TagLibParseCookie; 27 import org.netbeans.modules.web.core.syntax.spi.ErrorAnnotation; 28 import org.openide.ErrorManager; 29 import org.openide.util.RequestProcessor; 30 import org.openide.util.RequestProcessor.Task; 31 import org.openide.filesystems.FileObject; 32 import org.netbeans.modules.web.jsps.parserapi.JspParserAPI; 33 import org.netbeans.modules.web.jsps.parserapi.JspParserFactory; 34 import org.netbeans.modules.web.jsps.parserapi.PageInfo; 35 import org.netbeans.modules.web.core.syntax.spi.JSPColoringData; 36 import org.netbeans.modules.web.api.webmodule.WebModule; 37 import org.openide.filesystems.FileUtil; 38 39 50 public class TagLibParseSupport implements org.openide.nodes.Node.Cookie, TagLibParseCookie { 51 52 private FileObject jspFile; 53 54 private boolean documentDirty; 56 private RequestProcessor.Task parsingTask = null; 57 private static RequestProcessor requestProcessor; 58 59 private Object openedLock = new Object (); private boolean opened; private static final int WAIT_FOR_EDITOR_TIMEOUT = 15 * 1000; 63 64 private WeakReference jspColoringDataRef; 65 66 67 private TimeReference jspOpenInfoRef; 68 69 73 private SoftReference parseResultRef; 74 75 79 private SoftReference parseResultSuccessfulRef; 80 81 private Object parseResultLock = new Object (); 82 private Object openInfoLock = new Object (); 83 84 87 private Object parseResultSuccessfulRefStrongReference = null; 88 89 private boolean wasAnEditorPaneChangeEvent = false; 92 93 private boolean parsingTaskCancelled = false; 94 95 97 private ErrorAnnotation annotations; 98 101 public TagLibParseSupport(FileObject jspFile) { 102 this.jspFile = jspFile; 103 if(requestProcessor == null) requestProcessor = new RequestProcessor("background jsp parsing", 10); annotations = new ErrorAnnotation (jspFile); 107 } 108 109 110 public JSPColoringData getJSPColoringData() { 111 return getJSPColoringData(true); 112 } 113 114 private WebModule getWebModule(FileObject fo){ 115 WebModule wm = WebModule.getWebModule(fo); 116 if (wm != null){ 117 FileObject wmRoot = wm.getDocumentBase(); 118 if (wmRoot != null && (fo == wmRoot || FileUtil.isParentOf(wmRoot, fo))) { 119 return wm; 120 } 121 } 122 return null; 123 } 124 125 JSPColoringData getJSPColoringData(boolean prepare) { 126 if (jspColoringDataRef != null) { 127 Object o = jspColoringDataRef.get(); 128 if (o != null) 129 return (JSPColoringData)o; 130 } 131 JSPColoringData jcd = new JSPColoringData(this); 132 jspColoringDataRef = new WeakReference (jcd); 133 if (prepare) { 134 prepare(); 135 } 136 return jcd; 137 } 138 139 140 void setDocumentDirty(boolean b) { 141 documentDirty = b; 143 } 145 146 147 boolean isDocumentDirty() { 148 return documentDirty; 149 } 150 151 155 Task autoParse() { 156 if(!isDocumentDirty()) { 160 return requestProcessor.post(new Runnable () { 161 public void run() { 162 } 164 }); 165 } else return parseObject(Thread.MIN_PRIORITY); 166 } 167 168 174 public Task prepare() { 175 return parseObject(Thread.MAX_PRIORITY - 1); 176 } 177 178 private Task parseObject(int priority) { 179 parsingTaskCancelled = false; 181 182 if(!wasAnEditorPaneChangeEvent) 184 ErrorManager.getDefault().annotate(new IllegalStateException (), 185 "The TagLibParseSupport.parseObject() is called before editor support is created!"); 187 synchronized (parseResultLock) { 188 RequestProcessor.Task t = parsingTask; 189 190 if (t != null) { 191 t.setPriority(Math.max(t.getPriority(), priority)); 192 return t; 193 } 194 195 setDocumentDirty(false); 196 t = requestProcessor.post(new ParsingRunnable(), 0, priority); 197 parsingTask = t; 198 return parsingTask; 199 } 200 } 201 202 203 void setEditorOpened(boolean state) { 205 wasAnEditorPaneChangeEvent = true; 207 208 synchronized (openedLock) { 209 opened = state; 210 if(opened) { 211 openedLock.notifyAll(); 212 } else { 213 parseResultSuccessfulRefStrongReference = null; 215 } 216 } 217 218 } 219 220 void cancelParsingTask() { 221 if(parsingTask != null) { 222 boolean removed = parsingTask.cancel(); 224 parsingTask = null; 225 jspColoringDataRef = null; 226 } 227 228 parsingTaskCancelled = true; 230 synchronized (openedLock) { 231 openedLock.notifyAll(); 232 } 233 } 234 235 public JspParserAPI.JspOpenInfo getCachedOpenInfo(boolean preferCurrent, boolean useEditor) { 236 synchronized (openInfoLock) { 237 if (preferCurrent) 238 jspOpenInfoRef = null; 239 long timestamp = jspFile.lastModified().getTime(); 240 if (jspOpenInfoRef == null) { 241 jspOpenInfoRef = new TimeReference(); 242 } 243 JspParserAPI.JspOpenInfo info = (JspParserAPI.JspOpenInfo)jspOpenInfoRef.get(timestamp); 244 if (info == null) { 245 info = JspParserFactory.getJspParser().getJspOpenInfo(jspFile, JspParserAccess.getJspParserWM (getWebModule (jspFile)), useEditor); 246 jspOpenInfoRef.put(info, timestamp); 247 } 248 return info; 249 } 250 } 251 252 public JspParserAPI.ParseResult getCachedParseResult(boolean successfulOnly, boolean preferCurrent) { 253 return getCachedParseResult(successfulOnly, preferCurrent, false); 254 } 255 256 265 public JspParserAPI.ParseResult getCachedParseResult(boolean successfulOnly, boolean preferCurrent, boolean forceParse) { 266 boolean needToParse = forceParse; 267 268 if (preferCurrent && isDocumentDirty()) { 269 needToParse = true; 271 } 272 if (parseResultRef == null) { 273 needToParse = true; 275 } 276 277 JspParserAPI.ParseResult ret = null; 278 SoftReference myRef = successfulOnly ? parseResultSuccessfulRef : parseResultRef; 279 if (myRef != null) { 280 ret = (JspParserAPI.ParseResult)myRef.get(); 281 } 282 283 if ((ret == null) && (!successfulOnly)) { 284 needToParse = true; 286 } 287 288 if (needToParse) { 289 RequestProcessor.Task t = prepare(); t.waitFinished(); 292 myRef = successfulOnly ? parseResultSuccessfulRef : parseResultRef; 293 if (myRef != null) { 294 ret = (JspParserAPI.ParseResult)myRef.get(); 295 } 296 } 297 return ret; 298 } 299 300 private boolean hasError = false; 302 303 private class ParsingRunnable implements Runnable { 304 305 309 JspParserAPI.ParseResult locResult = null; 310 311 public ParsingRunnable () { 312 } 313 314 public void run() { 315 synchronized(TagLibParseSupport.this.openedLock) { 317 if(!opened) { 318 try { 319 TagLibParseSupport.this.openedLock.wait(WAIT_FOR_EDITOR_TIMEOUT); 321 }catch(InterruptedException e) { } 322 323 Thread.currentThread().setPriority(Thread.NORM_PRIORITY - 1); 327 } 328 } 329 long a = System.currentTimeMillis(); 330 if(!parsingTaskCancelled && getWebModule(jspFile) != null) { 334 JspParserAPI parser = JspParserFactory.getJspParser(); 335 if (parser == null) { 337 throw new InternalError (); 338 } 339 340 getJSPColoringData(false).parsingStarted(); 341 342 locResult = parser.analyzePage(jspFile, JspParserAccess.getJspParserWM (getWebModule (jspFile)), JspParserAPI.ERROR_IGNORE); 343 assert locResult != null; 344 345 synchronized (TagLibParseSupport.this.parseResultLock) { 346 parseResultRef = new SoftReference (locResult); 347 if (locResult.isParsingSuccess()) { 348 parseResultSuccessfulRef = new SoftReference (locResult); 349 parseResultSuccessfulRefStrongReference = locResult; 353 if (hasError){ 355 SwingUtilities.invokeLater(new Runnable () { 357 public void run() { 358 annotations.annotate(new ErrorAnnotation.ErrorInfo[] {}); 359 } 360 }); 361 hasError = false; 362 } 363 } else { 364 SwingUtilities.invokeLater(new Runnable () { 365 public void run() { 366 for (int i = 0; i < locResult.getErrors().length; i ++){ 367 JspParserAPI.ErrorDescriptor err = locResult.getErrors()[i]; 368 annotations.annotate(new ErrorAnnotation.ErrorInfo[] { 369 new ErrorAnnotation.ErrorInfo(translate(err.getErrorMessage()), 370 err.getLine(), 371 err.getColumn(), 372 ErrorAnnotation.JSP_ERROR) 373 } ); 374 } 375 if (!hasError){ 377 hasError = true; 378 } 379 380 } 381 }); 382 } 383 PageInfo pageInfo = locResult.getPageInfo(); 384 385 parsingTask = null; 387 388 if (pageInfo == null) return; 389 Map prefixMapper = null; 393 if (pageInfo.getXMLPrefixMapper().size() > 0) { 394 prefixMapper = pageInfo.getApproxXmlPrefixMapper(); 395 if (prefixMapper.size() == 0){ 396 prefixMapper = pageInfo.getXMLPrefixMapper(); 397 } 398 prefixMapper.putAll(pageInfo.getJspPrefixMapper()); 399 } 400 else { 401 prefixMapper = pageInfo.getJspPrefixMapper(); 402 } 403 getJSPColoringData(false).applyParsedData(pageInfo.getTagLibraries(), prefixMapper, 404 pageInfo.isELIgnored(), getCachedOpenInfo(false, false).isXmlSyntax(), 405 locResult.isParsingSuccess()); 406 } 407 } 408 409 410 } 411 412 private String translate (String text){ 413 String value = text.replaceAll("<", "<"); 414 value = value.replaceAll(">", ">"); 415 return value; 416 } 417 418 } 419 420 } 421 | Popular Tags |