Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2014-2015 Red Hat, Inc. and/or its affiliates
   * and other contributors as indicated by the @author tags.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package org.hawkular.build.checkstyle.xml;
 
 import java.io.File;
 import java.io.Reader;
 import java.util.List;
 
 
 

Author(s):
Peter Palaga
 
 public final class XmlIndentCheck extends AbstractFileSetCheck {
    
An entry that can be stored in a stack
 
     private static class ElementEntry {
         private final String elementName;
         private final Indent expectedIndent;
         private final Indent foundIndent;
 
         public ElementEntry(String elementNameIndent foundIndent) {
             super();
             this. = elementName;
             this. = foundIndent;
             this. = foundIndent;
         }
 
         public ElementEntry(String elementNameIndent foundIndent,
                 Indent expectedIndent) {
             super();
             this. = elementName;
             this. = foundIndent;
             this. = expectedIndent;
         }
 
         @Override
         public String toString() {
             return "<" +  + "> " + ;
         }
     }

    
An indent occurrence within a file characterized by lineNumber and size.
 
     private static class Indent {

        
An Indent usable at the beginning of a typical XML file.
 
         public static final Indent START = new Indent(1, 0);

        
The number of spaces in this Indent.
 
         private final int size;

        
The line number where this Indent occurs. The first line number in a file is 1.
 
         private final int lineNumber;
 
         public Indent(int lineNumberint size) {
             super();
             this. = lineNumber;
             this. = size;
         }
 
         @Override
         public String toString() {
            return "Indent [size=" +  + ", lineNumber=" +  + "]";
        }
    }
    private class IndentHandler extends DefaultHandler {
        private final StringBuilder charBuffer = new StringBuilder();
        private int charLineNumber;
        private Indent lastIndent = .;
        private Locator locator;
        private FastStack<ElementEntrystack = FastStack.newInstance();

        
Stores the passed characters into charBuffer.

See also:
org.xml.sax.helpers.DefaultHandler.characters(char[], int, int)
        @Override
        public void characters(char[] chint startint length)
                throws SAXException {
            .append(chstartlength);
             = .getLineNumber();
        }

        
Checks indentation for an end element.

See also:
org.xml.sax.helpers.DefaultHandler.startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
        @Override
        public void endElement(String uriString localNameString qName)
                throws SAXException {
            flushCharacters();
            if (.isEmpty()) {
                throw new IllegalStateException(
                        "Stack must not be empty when closing the element "
                                + qName + " around line "
                                + .getLineNumber() + " and column "
                                + .getColumnNumber());
            }
            ElementEntry startEntry = .pop();
            int indentDiff = . - startEntry.expectedIndent.size;
            int expectedIndent = startEntry.expectedIndent.size;
            if (. != startEntry.foundIndent.lineNumber
                    && indentDiff != 0) {
                /*
                 * diff should be zero unless we are on the same line as start
                 * element
                 */
                log(.getLineNumber(), .getColumnNumber(),
                        "Expected indent {0} before end element {1}",
                        expectedIndent"</" + qName + ">");
            }
        }

        
Sets lastIndent based on charBuffer and resets charBuffer.
        private void flushCharacters() {
            int indentLength = 0;
            int len = .length();
            /*
             * Count characters from end of ignorable whitespace to first end of
             * line we hit
             */
            for (int i = len - 1; i >= 0; i--) {
                char ch = .charAt(i);
                switch (ch) {
                case '\n':
                case '\r':
                     = new Indent(indentLength);
                    .setLength(0);
                    return;
                case ' ':
                case '\t':
                    indentLength++;
                    break;
                default:
                    /*
                     * No end of line foundIndent in the trailing whitespace.
                     * Leave the foundIndent from previous ignorable whitespace
                     * unchanged
                     */
                    .setLength(0);
                    return;
                }
            }
        }

        
Just delegates to characters(char[], int, int), since this method is not called in all situations where it could be naively expected.

See also:
org.xml.sax.helpers.DefaultHandler.ignorableWhitespace(char[], int, int)
        @Override
        public void ignorableWhitespace(char[] charsint startint length)
                throws SAXException {
            characters(charsstartlength);
        }

        
Always returns an empty InputSource to avoid loading of any DTDs.

See also:
org.xml.sax.helpers.DefaultHandler.resolveEntity(java.lang.String, java.lang.String)
        @Override
        public InputSource resolveEntity(String publicIdString systemId)
                throws SAXExceptionIOException {
            return new InputSource(new StringReader(""));
        }

        

See also:
org.xml.sax.helpers.DefaultHandler.setDocumentLocator(org.xml.sax.Locator)
        @Override
        public void setDocumentLocator(Locator locator) {
            this. = locator;
        }

        
Checks indentation for a start element.

See also:
org.xml.sax.helpers.DefaultHandler.startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
        @Override
        public void startElement(String uriString localNameString qName,
                Attributes attributesthrows SAXException {
            flushCharacters();
            ElementEntry currentEntry = new ElementEntry(qName);
            if (!.isEmpty()) {
                ElementEntry parentEntry = .peek();
                /*
                 * note that we use parentEntry.expectedIndent rather than
                 * parentEntry.foundIndent this is to make the messages more
                 * useful
                 */
                int indentDiff = currentEntry.foundIndent.size
                        - parentEntry.expectedIndent.size;
                int expectedIndent = parentEntry.expectedIndent.size
                        + ;
                if (indentDiff == 0
                        && currentEntry.foundIndent.lineNumber == parentEntry.foundIndent.lineNumber) {
                    /*
                     * Zero foundIndent acceptable only if current is on the
                     * same line as parent This is OK, therefore do nothing
                     */
                } else if (indentDiff != ) {
                    /* generally unexpected foundIndent */
                    log(.getLineNumber(), .getColumnNumber(),
                            "Expected indent {0} before start element {1}",
                            expectedIndent"<" + currentEntry.elementName
                                    + ">");
                    /* reset the expected inden in the entry we'll push */
                    currentEntry = new ElementEntry(qName,
                            new Indent(.expectedIndent));
                }
            }
            .push(currentEntry);
        }
    }

    
The default indent size: spaces.
    public static final int DEFAULT_INDENT_SIZE = 4;

    
The "indentSize" string.
    public static final String INDENT_SIZE_ATTRIBUTE = "indentSize";

    
The encoding used to read the XML files.
    private String encoding;

    
The number of spaces expected for indentation.
    private int indentSize;

    
A SAXParserFactory
    private SAXParserFactory saxParserFactory;

    
Creates a new XmlIndentCheck instance.
    public XmlIndentCheck() {
        super();
        this. = ;
        setFileExtensions(new String[] { ".xml" });
        this. = SAXParserFactory.newInstance();
        this..setValidating(false);
    }

    

See also:
com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck.beginProcessing(java.lang.String)
    @Override
    public void beginProcessing(String aCharset) {
        this. = aCharset;
    }

    

Returns:
the number of spaces for indentation
    public int getIndentSize() {
        return ;
    }

    

See also:
com.puppycrawl.tools.checkstyle .api.AbstractFileSetCheck.processFiltered(java.io.File, java.util.List)
    @Override
    protected void processFiltered(File aFileList<StringaLines) {
        Reader in = null;
        try {
            in = new InputStreamReader(new FileInputStream(aFile), );
            SAXParser saxParser = .newSAXParser();
            DefaultHandler handler = new IndentHandler();
            saxParser.parse(new InputSource(in), handler);
        } catch (SAXException e) {
            log(0, "SAXException: {0}"e.getMessage());
        } catch (IOException e) {
            log(0, "IOException: {0}"e.getMessage());
        } catch (ParserConfigurationException e) {
            throw new RuntimeException(e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }

    
Sets the number of spaces for indentation.

Parameters:
indentSize the number of spaces
    public void setIndentSize(int indentSize) {
        this. = indentSize;
    }
New to GrepCode? Check out our FAQ X