001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.tools.ant.types.resources;
019:
020: import java.io.InputStreamReader;
021: import java.io.IOException;
022: import java.io.UnsupportedEncodingException;
023: import java.util.Stack;
024: import java.util.ArrayList;
025: import java.util.Collection;
026: import java.util.Collections;
027:
028: import org.apache.tools.ant.Project;
029: import org.apache.tools.ant.BuildException;
030: import org.apache.tools.ant.types.DataType;
031: import org.apache.tools.ant.types.ResourceCollection;
032: import org.apache.tools.ant.util.ConcatResourceInputStream;
033: import org.apache.tools.ant.util.LineTokenizer;
034: import org.apache.tools.ant.util.Tokenizer;
035:
036: /**
037: * ResourceCollection consisting of StringResources gathered from tokenizing
038: * another ResourceCollection with a Tokenizer implementation.
039: * @since Ant 1.7
040: */
041: public class Tokens extends BaseResourceCollectionWrapper {
042:
043: private Tokenizer tokenizer;
044: private String encoding;
045:
046: /**
047: * Sort the contained elements.
048: * @return a Collection of Resources.
049: */
050: protected synchronized Collection getCollection() {
051: ResourceCollection rc = getResourceCollection();
052: if (rc.size() == 0) {
053: return Collections.EMPTY_SET;
054: }
055: if (tokenizer == null) {
056: tokenizer = new LineTokenizer();
057: }
058: ConcatResourceInputStream cat = new ConcatResourceInputStream(
059: rc);
060: cat.setManagingComponent(this );
061:
062: InputStreamReader rdr = null;
063: if (encoding == null) {
064: rdr = new InputStreamReader(cat);
065: } else {
066: try {
067: rdr = new InputStreamReader(cat, encoding);
068: } catch (UnsupportedEncodingException e) {
069: throw new BuildException(e);
070: }
071: }
072: ArrayList result = new ArrayList();
073: try {
074: for (String s = tokenizer.getToken(rdr); s != null; s = tokenizer
075: .getToken(rdr)) {
076: result.add(new StringResource(s));
077: }
078: } catch (IOException e) {
079: throw new BuildException("Error reading tokens", e);
080: }
081: return result;
082: }
083:
084: /**
085: * Set the encoding used to create the tokens.
086: * @param encoding the encoding to use.
087: */
088: public synchronized void setEncoding(String encoding) {
089: this .encoding = encoding;
090: }
091:
092: /**
093: * Add the nested Tokenizer to this Tokens ResourceCollection.
094: * A LineTokenizer will be used by default.
095: * @param tokenizer the tokenizer to add.
096: */
097: public synchronized void add(Tokenizer tokenizer) {
098: if (isReference()) {
099: throw noChildrenAllowed();
100: }
101: if (this .tokenizer != null) {
102: throw new BuildException(
103: "Only one nested tokenizer allowed.");
104: }
105: this .tokenizer = tokenizer;
106: }
107:
108: /**
109: * Overrides the BaseResourceCollectionContainer version
110: * to check the nested Tokenizer.
111: * @param stk the stack of data types to use (recursively).
112: * @param p the project to use to dereference the references.
113: * @throws BuildException on error.
114: */
115: protected synchronized void dieOnCircularReference(Stack stk,
116: Project p) throws BuildException {
117: if (isChecked()) {
118: return;
119: }
120: if (isReference()) {
121: super .dieOnCircularReference(stk, p);
122: } else {
123: if (tokenizer instanceof DataType) {
124: stk.push(tokenizer);
125: invokeCircularReferenceCheck((DataType) tokenizer, stk,
126: p);
127: }
128: setChecked(true);
129: }
130: }
131:
132: }
|