1 11 package org.eclipse.ant.internal.ui.editor.formatter; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.List ; 16 17 import org.eclipse.ant.internal.ui.editor.templates.AntContext; 18 import org.eclipse.ant.internal.ui.editor.text.AntDocumentSetupParticipant; 19 import org.eclipse.ant.internal.ui.editor.text.AntEditorPartitionScanner; 20 import org.eclipse.ant.internal.ui.model.AntElementNode; 21 import org.eclipse.ant.internal.ui.model.AntProjectNode; 22 import org.eclipse.ant.internal.ui.model.IAntModel; 23 import org.eclipse.core.runtime.Assert; 24 import org.eclipse.jface.text.BadLocationException; 25 import org.eclipse.jface.text.BadPositionCategoryException; 26 import org.eclipse.jface.text.DefaultPositionUpdater; 27 import org.eclipse.jface.text.Document; 28 import org.eclipse.jface.text.IDocument; 29 import org.eclipse.jface.text.IRegion; 30 import org.eclipse.jface.text.Position; 31 import org.eclipse.jface.text.Region; 32 import org.eclipse.jface.text.formatter.MultiPassContentFormatter; 33 import org.eclipse.jface.text.templates.TemplateBuffer; 34 import org.eclipse.jface.text.templates.TemplateVariable; 35 36 40 public class XmlFormatter { 41 42 private static final String POS_CATEGORY= "tempAntFormatterCategory"; 44 55 public static String format(String text, FormattingPreferences prefs) { 56 57 return format(text, prefs, -1); 58 } 59 60 private static String format(String text, FormattingPreferences prefs, int indent) { 61 Assert.isNotNull(text); 62 63 FormattingPreferences applyPrefs; 64 if(prefs == null) { 65 applyPrefs = new FormattingPreferences(); 66 } else { 67 applyPrefs = prefs; 68 } 69 70 IDocument doc = new Document(); 71 doc.set(text); 72 new AntDocumentSetupParticipant().setup(doc); 73 74 format(applyPrefs, doc, indent); 75 76 return doc.get(); 77 } 78 79 private static void format(FormattingPreferences prefs, IDocument doc, int indent) { 80 MultiPassContentFormatter formatter = new MultiPassContentFormatter( 81 AntDocumentSetupParticipant.ANT_PARTITIONING, 82 IDocument.DEFAULT_CONTENT_TYPE); 83 84 formatter.setMasterStrategy(new XmlDocumentFormattingStrategy(prefs, indent)); 85 formatter.setSlaveStrategy(new XmlElementFormattingStrategy(prefs), 86 AntEditorPartitionScanner.XML_TAG); 87 formatter.format(doc, new Region(0, doc.getLength())); 88 } 89 90 98 public static String format(String text) { 99 return format(text,null); 100 } 101 102 public static void format(TemplateBuffer templateBuffer, AntContext antContext, FormattingPreferences prefs) { 103 String templateString= templateBuffer.getString(); 104 IDocument fullDocument= new Document(antContext.getDocument().get()); 105 106 int completionOffset= antContext.getCompletionOffset(); 107 try { 108 IRegion lineRegion= fullDocument.getLineInformationOfOffset(completionOffset); 110 String lineString= fullDocument.get(lineRegion.getOffset(), lineRegion.getLength()); 111 lineString= trimBegin(lineString); 112 fullDocument.replace(lineRegion.getOffset(), lineRegion.getLength(), lineString); 113 } catch (BadLocationException e1) { 114 return; 115 } 116 TemplateVariable[] variables= templateBuffer.getVariables(); 117 int[] offsets= variablesToOffsets(variables, completionOffset); 118 119 IDocument origTemplateDoc= new Document(fullDocument.get()); 120 try { 121 origTemplateDoc.replace(completionOffset, antContext.getCompletionLength(), templateString); 122 } catch (BadLocationException e) { 123 return; } 125 126 IDocument templateDocument= createDocument(origTemplateDoc.get(), createPositions(offsets)); 127 128 String leadingText= getLeadingText(fullDocument, antContext.getAntModel(), completionOffset); 129 String newTemplateString= leadingText + templateString; 130 int indent= XmlDocumentFormatter.computeIndent(leadingText, prefs.getTabWidth()); 131 132 newTemplateString= format(newTemplateString, prefs, indent); 133 134 try { 135 templateDocument.replace(completionOffset, templateString.length(), newTemplateString); 136 } catch (BadLocationException e) { 137 return; 138 } 139 Position[] positions= null; 140 try { 141 positions= templateDocument.getPositions(POS_CATEGORY); 142 } catch (BadPositionCategoryException e2) { 143 } 144 positionsToVariables(positions, variables, completionOffset); 146 templateBuffer.setContent(newTemplateString, variables); 147 } 148 149 private static void positionsToVariables(Position[] positions, TemplateVariable[] variables, int start) { 150 for (int i= 0; i != variables.length; i++) { 151 TemplateVariable variable= variables[i]; 152 153 int[] offsets= new int[variable.getOffsets().length]; 154 for (int j= 0; j != offsets.length; j++) { 155 offsets[j]= positions[j].getOffset() - start; 156 } 157 158 variable.setOffsets(offsets); 159 } 160 } 161 private static Document createDocument(String string, Position[] positions) throws IllegalArgumentException { 162 Document doc= new Document(string); 163 try { 164 if (positions != null) { 165 166 doc.addPositionCategory(POS_CATEGORY); 167 doc.addPositionUpdater(new DefaultPositionUpdater(POS_CATEGORY) { 168 protected boolean notDeleted() { 169 if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) { 170 fPosition.offset= fOffset + fLength; return false; 172 } 173 return true; 174 } 175 }); 176 for (int i= 0; i < positions.length; i++) { 177 try { 178 doc.addPosition(POS_CATEGORY, positions[i]); 179 } catch (BadLocationException e) { 180 throw new IllegalArgumentException ("Position outside of string. offset: " + positions[i].offset + ", length: " + positions[i].length + ", string size: " + string.length()); } 182 } 183 } 184 } catch (BadPositionCategoryException cannotHappen) { 185 } 187 return doc; 188 } 189 190 public static String trimBegin(String toBeTrimmed) { 191 192 int i= 0; 193 while ((i != toBeTrimmed.length()) && Character.isWhitespace(toBeTrimmed.charAt(i))) { 194 i++; 195 } 196 197 return toBeTrimmed.substring(i); 198 } 199 200 private static int[] variablesToOffsets(TemplateVariable[] variables, int start) { 201 List list= new ArrayList (); 202 for (int i= 0; i != variables.length; i++) { 203 int[] offsets= variables[i].getOffsets(); 204 for (int j= 0; j != offsets.length; j++) { 205 list.add(new Integer (offsets[j])); 206 } 207 } 208 209 int[] offsets= new int[list.size()]; 210 for (int i= 0; i != offsets.length; i++) { 211 offsets[i]= ((Integer ) list.get(i)).intValue() + start; 212 } 213 214 Arrays.sort(offsets); 215 216 return offsets; 217 } 218 219 222 private static String getLeadingText(IDocument document, IAntModel model, int completionOffset) { 223 AntProjectNode project= model.getProjectNode(false); 224 if (project == null) { 225 return ""; } 227 AntElementNode node= project.getNode(completionOffset); if (node == null) { 229 return ""; } 231 232 StringBuffer buf= new StringBuffer (); 233 buf.append(XmlDocumentFormatter.getLeadingWhitespace(node.getOffset(), document)); 234 buf.append(XmlDocumentFormatter.createIndent()); 235 return buf.toString(); 236 } 237 238 private static Position[] createPositions(int[] positions) { 239 Position[] p= null; 240 241 if (positions != null) { 242 p= new Position[positions.length]; 243 for (int i= 0; i < positions.length; i++) { 244 p[i]= new Position(positions[i], 0); 245 } 246 } 247 return p; 248 } 249 } 250 | Popular Tags |