package thahn.java.agui.ide.eclipse.build.builder; import java.io.BufferedInputStream; import java.io.IOException; import java.nio.file.CopyOption; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; import thahn.java.agui.ide.eclipse.preferences.AguiPrefs; import thahn.java.agui.ide.eclipse.project.AguiConstants; import thahn.java.agui.ide.eclipse.project.AguiProjectInfo; import thahn.java.agui.ide.eclipse.project.BaseProjectHelper; import thahn.java.agui.ide.eclipse.wizard.AguiPlugin; import thahn.java.agui.ide.eclipse.wizard.AguiProjectMaker; import thahn.java.agui.ide.eclipse.wizard.template.ResourceIndicator; import thahn.java.agui.res.RBuilder; import thahn.java.agui.res.RMaker; import thahn.java.agui.res.ResourcesManager; public class ResourceBuilder extends IncrementalProjectBuilder { public static final String TAG = "ResourceBuilder"; class SampleDeltaVisitor implements IResourceDeltaVisitor { /* * (non-Javadoc) * * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta) */ public boolean visit(IResourceDelta delta) throws CoreException { IResource resource = delta.getResource(); switch (delta.getKind()) { case IResourceDelta.ADDED: // handle added resource checkXML(resource); break; case IResourceDelta.REMOVED: // handle removed resource break; case IResourceDelta.CHANGED: // handle changed resource checkXML(resource); break; } //return true to continue visiting children. return true; } } class SampleResourceVisitor implements IResourceVisitor { public boolean visit(IResource resource) { checkXML(resource); //return true to continue visiting children. return true; } } class XMLErrorHandler extends DefaultHandler { private IFile file; public XMLErrorHandler(IFile file) { this.file = file; } private void addMarker(SAXParseException e, int severity) { ResourceBuilder.this.addMarker(file, e.getMessage(), e .getLineNumber(), severity); } public void error(SAXParseException exception) throws SAXException { addMarker(exception, IMarker.SEVERITY_ERROR); } public void fatalError(SAXParseException exception) throws SAXException { addMarker(exception, IMarker.SEVERITY_ERROR); } public void warning(SAXParseException exception) throws SAXException { addMarker(exception, IMarker.SEVERITY_WARNING); } } public static final String BUILDER_ID = "thahn.java.agui.ide.eclipse.wizard.ResourceBuilder"; private static final String MARKER_TYPE = "thahn.java.agui.ide.eclipse.wizard.xmlProblem"; private SAXParserFactory parserFactory; private void addMarker(IFile file, String message, int lineNumber, int severity) { try { IMarker marker = file.createMarker(MARKER_TYPE); marker.setAttribute(IMarker.MESSAGE, message); marker.setAttribute(IMarker.SEVERITY, severity); if (lineNumber == -1) { lineNumber = 1; } marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); } catch (CoreException e) { } } /* * (non-Javadoc) * * @see org.eclipse.core.internal.events.InternalBuilder#build(int, * java.util.Map, org.eclipse.core.runtime.IProgressMonitor) */ protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { if (kind == FULL_BUILD) { fullBuild(monitor); } else { IResourceDelta delta = getDelta(getProject()); if (delta == null) { fullBuild(monitor); } else { incrementalBuild(delta, monitor); } } return null; } void checkXML(IResource resource) { if (resource instanceof IFile && resource.getName().endsWith(".xml")) { IFile file = (IFile) resource; deleteMarkers(file); XMLErrorHandler reporter = new XMLErrorHandler(file); try { getParser().parse(file.getContents(), reporter); } catch (Exception e1) { } } } private void deleteMarkers(IFile file) { try { file.deleteMarkers(MARKER_TYPE, false, IResource.DEPTH_ZERO); } catch (CoreException ce) { } } protected void fullBuild(final IProgressMonitor monitor) throws CoreException { try { getProject().accept(new SampleResourceVisitor()); } catch (CoreException e) { } } private SAXParser getParser() throws ParserConfigurationException, SAXException { if (parserFactory == null) { parserFactory = SAXParserFactory.newInstance(); } return parserFactory.newSAXParser(); } protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException { // the visitor does the work. delta.accept(new SampleDeltaVisitor()); final IProject project = delta.getResource().getProject(); if (BaseProjectHelper.isAguiProject(project)) { // get AguiManifest info AguiProjectInfo aguiInfo = BaseProjectHelper.getAguiProjectInfo(project); // BuildConfig.java AguiProjectMaker maker = new AguiProjectMaker(aguiInfo.projectName, aguiInfo.packageName, aguiInfo.mainActivityName); try (BufferedInputStream buildConfigBis = new BufferedInputStream(maker.copyTemplate("BuildConfigTemplate.txt"))) { Files.copy(buildConfigBis, Paths.get(aguiInfo.projectPath, "gen" , aguiInfo.packageName.replace(".", "/"), AguiConstants.BUILD_CONFIG_JAVA) , new CopyOption[] { StandardCopyOption.REPLACE_EXISTING }); } catch (IOException e) { e.printStackTrace(); AguiPlugin.displayError("Build Error", e.getMessage()); } // R.java String aguiCorePackageName = thahn.java.agui.Main.class.getPackage().getName(); String aguiCorePath = AguiPrefs.getInstance().getSdkJarLocation(); // prepare resource container like enum resource, etc.. RMaker coreRMaker = new RMaker(true, aguiCorePackageName, aguiCorePath, aguiCorePath, aguiCorePath , ResourcesManager.getInstance(), aguiCorePackageName); coreRMaker.parse(); // make R.java RBuilder rBuilder = new RBuilder(aguiCorePackageName, aguiCorePath, aguiInfo.packageName, aguiInfo.projectPath); rBuilder.parse(); // refresh IFolder genFolder = project.getFolder(AguiConstants.FD_GEN); genFolder.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 10)); } } protected void launchJob(Job newJob) { newJob.setPriority(Job.BUILD); newJob.setRule(ResourcesPlugin.getWorkspace().getRoot()); newJob.schedule(); } @Override protected void clean(IProgressMonitor monitor) throws CoreException { super.clean(monitor); IProject project = getProject(); IFolder genFolder = project.getFolder(AguiConstants.FD_GEN); if (genFolder.exists()) { for(IResource res : genFolder.members()) { if (res.exists()) res.delete(true, new SubProgressMonitor(monitor, 10)); } } } }