package tk.eclipse.plugin.dtdeditor.editors; import java.io.File; import java.io.StringReader; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IStorageEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; import tk.eclipse.plugin.htmleditor.HTMLPlugin; import tk.eclipse.plugin.htmleditor.HTMLProjectParams; import tk.eclipse.plugin.htmleditor.editors.HTMLSourceEditor; import tk.eclipse.plugin.htmleditor.editors.IHTMLOutlinePage; import tk.eclipse.plugin.xmleditor.editors.SchemaGenerator; import com.wutka.dtd.DTDParseException; import com.wutka.dtd.DTDParser; /** * DTD editor. * * @author Naoki Takezoe */ public class DTDEditor extends HTMLSourceEditor { public static final String ACTION_GEN_XSD = "_generate_xsd"; public DTDEditor(){ super(new DTDConfiguration(HTMLPlugin.getDefault().getColorProvider())); setAction(ACTION_GEN_XSD,new GenerateXSDAction()); } @Override public void createPartControl(Composite parent) { super.createPartControl(parent); getPairMatcher().setDelimiter('<'); } @Override protected IDocumentProvider createDocumentProvider(IEditorInput input){ if(input instanceof IFileEditorInput){ return new DTDTextDocumentProvider(); } else if(input instanceof IStorageEditorInput){ return new DTDFileDocumentProvider(); } else { return new DTDTextDocumentProvider(); } } @Override protected IHTMLOutlinePage createOutlinePage() { return new DTDOutlinePage(this); } @Override protected void addContextMenuActions(IMenuManager menu){ menu.add(new Separator(GROUP_HTML)); addAction(menu,GROUP_HTML,ACTION_COMMENT); addAction(menu,GROUP_HTML,ACTION_GEN_XSD); } @Override protected void doValidate() { try { ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { IFileEditorInput input = (IFileEditorInput)getEditorInput(); IFile file = input.getFile(); file.deleteMarkers(IMarker.PROBLEM,false,0); try { HTMLProjectParams params = new HTMLProjectParams(file.getProject()); if(!params.getValidateDTD()){ return; } new DTDParser(new StringReader(getHTMLSource())).parse(); } catch(DTDParseException ex){ DTDErrorInfo error = new DTDErrorInfo(ex); IMarker marker = file.createMarker(IMarker.PROBLEM); Map<String, Object> map = new HashMap<String, Object>(); map.put(IMarker.SEVERITY, Integer.valueOf(IMarker.SEVERITY_ERROR)); map.put(IMarker.MESSAGE, error.getError()); map.put(IMarker.LINE_NUMBER,Integer.valueOf(error.getLine())); marker.setAttributes(map); } catch(Exception ex){ HTMLPlugin.logException(ex); } } },null); } catch(Exception ex){ HTMLPlugin.logException(ex); } } private static class DTDErrorInfo { private Pattern pattern = Pattern.compile("At line ([0-9]+), column ([0-9]+): (.+)$"); private int line; private int column; private String error; public DTDErrorInfo(DTDParseException ex){ Matcher matcher = pattern.matcher(ex.toString()); if(matcher.find()){ line = Integer.parseInt(matcher.group(1)); column = Integer.parseInt(matcher.group(2)); error = matcher.group(3); } } public int getColumn() { return column; } public String getError() { return error; } public int getLine() { return line; } } /** The action to generate XML schema from DTD. */ private class GenerateXSDAction extends Action { public GenerateXSDAction(){ super(HTMLPlugin.getResourceString("XMLEditor.GenerateXSD"), HTMLPlugin.getDefault().getImageRegistry().getDescriptor(HTMLPlugin.ICON_XSD)); } @Override public void run() { FileDialog dialog = new FileDialog(getViewer().getTextWidget().getShell(),SWT.SAVE); dialog.setFilterExtensions(new String[]{"*.xsd"}); String file = dialog.open(); if(file!=null){ try { SchemaGenerator.generateXSDFromDTD(getFile(),new File(file)); } catch(Exception ex){ HTMLPlugin.openAlertDialog(ex.toString()); } } } } }