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));
}
}
}
}