1 16 package scriptella.configuration; 17 18 import org.w3c.dom.Element ; 19 import org.w3c.dom.Node ; 20 import org.w3c.dom.Text ; 21 import scriptella.spi.Resource; 22 23 import java.io.BufferedReader ; 24 import java.io.IOException ; 25 import java.io.Reader ; 26 import java.util.ArrayList ; 27 import java.util.List ; 28 29 30 36 public class ContentEl extends XmlConfigurableBase implements Resource { 37 42 private static final int MAX_CONCAT_RESOURCE_LENGTH = 1024 * 128; private List <Resource> content = new ArrayList <Resource>(); 44 47 public static final Resource NULL_CONTENT = new StringResource("", "Empty Content"); 48 49 public ContentEl() { 50 } 51 52 public ContentEl(XmlElement element) { 53 configure(element); 54 } 55 56 public Reader open() throws IOException { 57 if (content.isEmpty()) { 58 return NULL_CONTENT.open(); 59 } 60 if (content.size() == 1) { 62 return content.get(0).open(); 63 } 64 return new BufferedReader (new MultipartReader()); 66 } 67 68 public void configure(final XmlElement element) { 69 for (Node node = element.getElement().getFirstChild(); node != null; node = node.getNextSibling()) { 70 append(asResource(element, node)); 71 } 72 } 73 74 75 83 static Resource asResource(final XmlElement parentElement, final Node node) { 84 if (node == null) { 85 return null; 86 } 87 if (node instanceof Text ) { 88 return new StringResource(((Text ) node).getData()); 89 } else if (node instanceof Element && "include".equals(node.getNodeName())) { 90 return new IncludeEl(new XmlElement((Element ) node, parentElement)); 91 } 92 return null; 93 94 95 } 96 97 103 final ContentEl merge(final ContentEl contentEl) { 104 content.addAll(contentEl.content); 105 return this; 106 } 107 108 113 final void append(final Resource resource) { 114 if (resource != null) { 115 if (resource instanceof StringResource && !content.isEmpty()) { 117 final int lastIndex = content.size() - 1; 118 Resource last = content.get(lastIndex); 119 if (last instanceof StringResource) { StringResource nextRes = (StringResource) resource; 122 StringResource prevRes = (StringResource) last; 123 if (prevRes.getString().length() + nextRes.getString().length() < MAX_CONCAT_RESOURCE_LENGTH) { 124 content.set(lastIndex, new StringResource(prevRes.getString() + nextRes.getString())); 125 return; 126 } 127 } 128 } 129 content.add(resource); 130 } 131 } 132 133 @Override 134 public String toString() { 135 Location loc = getLocation(); 136 return loc != null ? loc.toString() : ("ContentEl{" + "content=" + content + '}'); 137 } 138 139 class MultipartReader extends Reader { 140 private int pos = 0; 141 private Reader current; 142 private int blocksCount=content.size(); 143 144 public int read(final char cbuf[], final int off, final int len) throws IOException { 145 if ((pos < 0) || ((pos >= blocksCount) && (current == null))) { 146 return -1; 147 } 148 149 int l = len; 150 int o = off; 151 152 while (l > 0) { 153 if (current == null) { 154 if (pos < blocksCount) { 155 current = content.get(pos).open(); 156 pos++; 157 } else { 158 return ((len - l) <= 0) ? (-1) : (len - l); 159 } 160 } else { 161 final int r = current.read(cbuf, o, l); 162 163 if (r <= 0) { 164 current.close(); 165 current = null; 166 } else if (r <= l) { 167 l -= r; 168 o += r; 169 } 170 } 171 } 172 173 return len - l; 174 } 175 176 public void close() throws IOException { 177 if (current != null) { 178 current.close(); 179 current = null; 180 } 181 182 pos = -1; 183 } 184 } 185 } 186 | Popular Tags |