All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.simpleframework.xml.stream.Indenter Maven / Gradle / Ivy

Go to download

Simple is a high performance XML serialization and configuration framework for Java

The newest version!
/*
 * Indenter.java July 2006
 *
 * Copyright (C) 2006, Niall Gallagher 
 *
 * 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.simpleframework.xml.stream;

/**
 * The Indenter is used create indent strings using the
 * stack paradigm. This allows XML documents to be generated by 
 * pushing and popping indents onto the stack. This indenter caches
 * all indent strings created so that when the same position on the
 * stack is encountered the indent can be acquired quickly.
 * 

* The indents created by this are all prefixed with the line feed * character, which allows XML tags to span exclusive lines. If the * indent size specified is zero or less then no spaces, or line * feed will be added to the generated indent string. * * @author Niall Gallagher */ class Indenter { /** * Provides a quick string cache that caches using by index. */ private Cache cache; /** * Number of spaces that is used for each of the indents. */ private int indent; /** * Represents the current number of spaces in the indent text. */ private int count; /** * Represents the index within the cache to get the indent. */ private int index; /** * Constructor for the Indenter object. This will * create an indent that uses three spaces for each indent that * is pushed on to the stack. This also uses a default cache * size of sixteen, which should be sufficient for most files. */ public Indenter() { this(new Format()); } /** * Constructor for the Indenter object. This will * create an indent that uses the specified number of spaces to * create each entry pushed on to the stack. This uses a cache * size of sixteen, which should be sufficient for most files. * * @param format determines the number of spaces per indent */ public Indenter(Format format) { this(format, 16); } /** * Constructor for the Indenter object. This will * create an indent that uses the specified number of spaces to * create each entry pushed on to the stack. This uses a cache * of the specified size, which is used to optimize the object. * * @param format determines the number of spaces per indent * @param size this is the initial size of the indent cache */ private Indenter(Format format, int size) { this.indent = format.getIndent(); this.cache = new Cache(size); } /** * This returns the current indent for this indenter. This should * be used to write elements or comments that should be at the * same indentation level as the XML element that will follow. * * @return this returns the current indentation level for this */ public String top() { return indent(index); } /** * This is used to push an indent on to the cache. The first * indent created by this is an empty string, this is because an * indent is not required for the start of an XML file. If there * are multiple roots written to the same writer then the start * and end tags of a root element will exist on the same line. * * @return this is used to push an indent on to the stack */ public String push() { String text = indent(index++); if(indent > 0) { count += indent; } return text; } /** * This is used to pop an indent from the cache. This reduces * the length of the current indent and is typically used when * an end tag is added to an XML document. If the number of pop * requests exceeds the number of push requests then an empty * string is returned from this method. * * @return this is used to pop an indent from the stack */ public String pop() { String text = indent(--index); if(indent > 0) { count -= indent; } return text; } /** * This is used to acquire the indent at the specified index. If * the indent does not exist at the specified index then on is * created using the current value of the indent. The very first * indent taken from this will be an empty string value. * * @param index this is the index to acquire the indent from * * @return this returns the indent from the specified index */ private String indent(int index) { if(indent > 0) { String text = cache.get(index); if(text == null){ text = create(); cache.set(index, text); } if(cache.size() >0) { return text; } } return ""; } /** * This is used to create an indent which can later be pushed on * to the stack. If the number of spaces to be added is zero then * this will return a single character string with a line feed. * * @return this will create an indent to be added to the stack */ private String create() { char[] text = new char[count+1]; if(count > 0) { text[0] = '\n'; for(int i = 1; i <= count; i++){ text[i] = ' '; } return new String(text); } return "\n"; } /** * The Cache object is used create an indexable list * which allows the indenter to quickly acquire an indent using * a stack position. This ensures that the indenter need only * create an index once for a given stack position. The number of * indents held within this cache can also be tracked. */ private static class Cache { /** * This is used to track indent strings within the cache. */ private String[] list; /** * Represents the number of indent strings held by the cache. */ private int count; /** * Constructor for the Cache object. This creates * a cache of the specified size, the specified size acts as * an initial size and the cache can be expanded on demand. * * @param size the initial number of entries in the cache */ public Cache(int size) { this.list = new String[size]; } /** * This method is used to retrieve the number of indents that * have been added to the cache. This is used to determine if * an indent request is the first. * * @return this returns the number of indents in the cache */ public int size() { return count; } /** * This method is used to add the specified indent on to the * cache. The index allows the cache to act as a stack, when * the index is specified it can be used to retrieve the same * indent using that index. * * @param index this is the position to add the index to * @param text this is the indent to add to the position */ public void set(int index, String text) { if(index >= list.length) { resize(index * 2); } if(index > count) { count = index; } list[index] = text; } /** * This method is used to retrieve an indent from the given * position. This allows the indenter to use the cache as a * stack, by increasing and decreasing the index as required. * * @param index the position to retrieve the indent from * * @return this is the indent retrieve from the given index */ public String get(int index) { if(index < list.length) { return list[index]; } return null; } /** * Should the number of indents to be cache grows larger than * the default initial size then this will increase the size * of the cache. This ensures that the indenter can handle an * arbitrary number of indents for a given output. * * @param size this is the size to expand the cache to */ private void resize(int size) { String[] temp = new String[size]; for(int i = 0; i < list.length; i++){ temp[i] = list[i]; } list = temp; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy