/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.markers; import java.util.HashSet; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.swt.widgets.Display; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.filesystems.impl.FolderImpl; import org.jboss.tools.common.model.util.EclipseResourceUtil; import org.jboss.tools.common.model.util.PositionHolder; public class ResourceMarkers { public static String TEXT_PROBLEM = "org.jboss.tools.common.model.textproblemmarker"; //$NON-NLS-1$ public static String CONSTRAINT_PROBLEM = "org.jboss.tools.jst.web.constraintsmarker"; //$NON-NLS-1$ public static String JST_WEB_PROBLEM = "org.jboss.tools.jst.web.strutsmarker"; //$NON-NLS-1$ public static String OLD_CONSTRAINT_PROBLEM = "org.jboss.tools.jst.web.ui.constraintsmarker"; //$NON-NLS-1$ public static String OLD_JST_WEB_PROBLEM = "org.jboss.tools.jst.web.ui.strutsmarker"; //$NON-NLS-1$ private XModelObject object; String type = null; String oldType = null; public ResourceMarkers(String type) { this.type = type; } public ResourceMarkers(String type, String oldType) { this.type = type; this.oldType = oldType; } public void setModelObject(XModelObject object) { this.object = object; } public void update() { if(object == null || !object.isActive()) return; update0(); } private void update0() { Set<XMarker> dms = null; Set<XMarker> added = null; IResource r = EclipseResourceUtil.getResource(object); if(r == null || !r.exists()) return; if(object.getParent() instanceof FolderImpl) { if( ((FolderImpl)object.getParent()).isOverlapped() ) { return; } } dms = getOwnedMarkers(r); String[] errorList = getErrors(); for (int i = 0; i < errorList.length; i++) { String error = errorList[i]; if(error == null || error.length() == 0) continue; String message = getTrueMessage(error); String path = getObjectPathForError(i); int location = getLocation(i); if(location < 0) location = getLocation(error); String attr = getObjectAttributeForError(i); XMarker marker = findMarker(path, message, attr, dms); if(marker != null) { dms.remove(marker); continue; } marker = new XMarker(); if(added == null) { added = new HashSet<XMarker>(); } added.add(marker); marker.setType(type); marker.setMessage(message); marker.setPath(path); if(attr != null && attr.length() > 0) { marker.setAttribute(attr); } } if(r instanceof IFile) { IFile file = (IFile)r; if(dms != null) { XMarkerManager.getInstance().clearXMarkers(file, dms); } if(added != null) { XMarkerManager.getInstance().addXMarkers(file, added); } if((dms != null && !dms.isEmpty()) || (added != null && !added.isEmpty())) { XMarkerManager.getInstance().forceReload(file); } } } public static void updateLocation(IMarker marker, int location, int start, int end) throws CoreException { if(location >= 0 && marker.getAttribute(IMarker.LINE_NUMBER, -1) != location) { marker.setAttribute(IMarker.LINE_NUMBER, location); } if(start >= 0 && marker.getAttribute(IMarker.CHAR_START, -1) != start) { marker.setAttribute(IMarker.CHAR_START, start); } if(end >= 0 && marker.getAttribute(IMarker.CHAR_END, -1) != end) { marker.setAttribute(IMarker.CHAR_END, end); } } private XMarker findMarker(String path, String message, String attr, Set<XMarker> dms) { if(dms == null) return null; for (XMarker m: dms) { if(!message.equals(m.getMessage())) continue; if(attr != null && !attr.equals(m.getAttribute())) continue; if(oldType != null && oldType.equals(m.getType())) continue; if(!path.equals(m.getPath())) { m.setPath(path); } return m; } return null; } protected String getObjectPathForError(int i) { return object == null ? null : object.getPath(); } protected String getObjectAttributeForError(int i) { return null; } protected String getTrueMessage(String message) { StringBuffer sb = new StringBuffer(); int c = 0; while(c < message.length()) { int i1 = message.indexOf('@', c); if(i1 < 0) break; int i2 = message.indexOf('@', i1 + 1); if(i2 < 0) break; int i3 = message.indexOf('@', i2 + 1); if(i3 < 0) break; if(c > 0) sb.append(message.substring(0, i1)); sb.append(message.substring(i2 + 1, i3)); c = i3 + 1; } sb.append(message.substring(c)); return sb.toString(); } public void clear() { IResource r = EclipseResourceUtil.getResource(object); if(!(r instanceof IFile)) return; Set<XMarker> ms = getOwnedMarkers((IFile)r); if(ms != null) { synchronized (XMarkerManager.getInstance()) { Set<XMarker> ms1 = XMarkerManager.getInstance().getMarkers((IFile)r); if(ms1 != null) { for (XMarker m: ms) ms1.remove(m); } } } } private Set<XMarker> getOwnedMarkers(IResource r) { if(!(r instanceof IFile)) { return null; } Set<XMarker> l = null; synchronized (XMarkerManager.getInstance()) { Set<XMarker> ms = XMarkerManager.getInstance().getMarkers((IFile)r); if(ms != null) for (XMarker m: ms) { if(isOwnedMarker(m)) { if(l == null) l = new HashSet<XMarker>(); l.add(m); } } } return l; } boolean isOwnedMarker(XMarker m) { if(m == null) return false; String _type = m.getType(); if(_type == null) return true; if(_type.startsWith("org.jboss.tools.")) { //$NON-NLS-1$ return _type.equals(type) || (oldType != null && _type.equals(oldType)); } return false; } protected String[] getErrors() { return new String[0]; } protected int getLocation(int i) { return -1; } protected int getLocation(String error) { return -1; } protected int getStart(int i) { return -1; } protected int getEnd(int i) { return -1; } public static void refreshProblemMarkersAsync(final XModelObject file) { if(!file.isActive()) return; Display.getDefault().asyncExec(new Runnable(){ public void run() { refreshProblemMarkers(file); } }); } public static void refreshProblemMarkers(XModelObject file) { IResource r = (IResource)file.getAdapter(IResource.class); if(r == null) return; try { IMarker[] ms = r.findMarkers(ResourceMarkers.JST_WEB_PROBLEM, true, 1); if(ms != null) for (int i = 0; i < ms.length; i++) { String path = ms[i].getAttribute("path", null); //$NON-NLS-1$ if(path == null) continue; XModelObject o = file.getModel().getByPath(path); if(o == null) { ms[i].delete(); continue; } String attr = ms[i].getAttribute("attribute", null); //$NON-NLS-1$ PositionHolder h = PositionHolder.getPosition(o, attr); h.update(); updateLocation(ms[i], h.getLine(), h.getStart(), h.getEnd()); } } catch (CoreException e) { //ignore } } }