package org.glassfish.pfl.basic.tools.file ;
import java.util.List ;
import java.util.Iterator ;
import java.util.ArrayList ;
import java.util.Set ;
import java.util.Map ;
import java.util.HashSet ;
import java.util.StringTokenizer ;
import java.io.IOException ;
import org.glassfish.pfl.basic.contain.Pair;
public class Block {
private List<String> data ;
private final Set<String> tags ;
private Block( final List<String> data, final Set<String> tags ) {
this.data = data ;
this.tags = tags ;
}
public Block( final List<String> data ) {
this.data = data ;
this.tags = new HashSet<String>() ;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder() ;
sb.append( "Block[" ) ;
boolean first = true ;
for (String tag : tags) {
if (first) {
first = false ;
} else {
sb.append( " " ) ;
}
sb.append( tag ) ;
}
sb.append( "]" ) ;
return sb.toString() ;
}
@Override
public boolean equals( Object obj ) {
if (obj == this) {
return true;
}
if (!(obj instanceof Block)) {
return false;
}
Block block = (Block)obj ;
Iterator<String> iter1 = data.iterator() ;
Iterator<String> iter2 = block.data.iterator() ;
while (iter1.hasNext() && iter2.hasNext()) {
String str1 = iter1.next() ;
String str2 = iter2.next() ;
if (!str1.equals( str2 )) {
return false;
}
}
return iter1.hasNext() == iter2.hasNext() ;
}
@Override
public int hashCode() {
int hash = 0 ;
for (String str : data) {
hash ^= data.hashCode();
}
return hash ;
}
public Block( final Block block ) {
this.data = new ArrayList<String>( block.data ) ;
this.tags = new HashSet<String>( block.tags ) ;
}
public void addTag( final String tag ) {
tags.add( tag ) ;
}
public boolean hasTag( final String tag ) {
return tags.contains( tag ) ;
}
public boolean hasTags( final String... tags ) {
for (String tag : tags) {
if (!hasTag( tag )) {
return false;
}
}
return true ;
}
public List<String> contents() {
return data ;
}
public void addBeforeFirst( final String str ) {
data.add( 0, str ) ;
}
public void addAfterLast( final String str ) {
data.add( data.size(), str ) ;
}
public void addPrefixToAll( String prefix ) {
final List<String> newData = new ArrayList<String>() ;
for (String str : data) {
newData.add( prefix + str ) ;
}
data = newData ;
}
public String find( final String search ) {
for (String str : data) {
if (str.contains( search )) {
return str;
}
}
return null ;
}
public void write( final FileWrapper fw ) throws IOException {
for (String str : data ) {
fw.writeLine( str ) ;
}
}
public Block instantiateTemplate( Map<String,String> parameters ) {
final List<String> result = new ArrayList<String>( data.size() ) ;
for (String str : data) {
final StringBuilder sb = new StringBuilder() ;
final StringTokenizer st = new StringTokenizer( str, "@" ) ;
boolean isKeyword = false ;
while (st.hasMoreTokens()) {
final String token = st.nextToken() ;
final String replacement =
isKeyword ? parameters.get( token ) : token ;
sb.append( replacement ) ;
isKeyword = !isKeyword ;
}
result.add( sb.toString() ) ;
}
return new Block( result ) ;
}
private String expandTabs( String src ) {
int outCtr = 0 ;
StringBuilder result = new StringBuilder() ;
for (int ctr=0; ctr<src.length(); ctr++) {
char ch = src.charAt( ctr ) ;
if (ch == '\t') {
int nextTab = ((outCtr >> 3) + 1) << 3 ;
while (outCtr < nextTab) {
result.append( ' ' ) ;
outCtr++ ;
}
} else {
result.append( ch ) ;
outCtr++ ;
}
}
return result.toString() ;
}
public Block expandTabs() {
List<String> result = new ArrayList<String>() ;
for (String line : data) {
String exp = expandTabs( line ) ;
result.add( exp ) ;
}
return new Block( result ) ;
}
public Block substitute( List<? extends Pair<String,String>> substitutions ) {
List<String> result = new ArrayList<String>() ;
for (String line : data) {
String newLine = line ;
for (Pair<String,String> pair : substitutions) {
String pattern = pair.first() ;
String replacement = pair.second() ;
newLine = newLine.replace( pattern, replacement ) ;
}
result.add( newLine ) ;
}
return new Block( result ) ;
}
public Pair<Block,Block> splitFirst() {
List<String> first = new ArrayList<String>() ;
List<String> rest = new ArrayList<String>() ;
for (String str : data) {
if (first.isEmpty()) {
first.add( str ) ;
} else {
rest.add( str ) ;
}
}
Block block1 = new Block( first, new HashSet<String>(tags) ) ;
Block block2 = new Block( rest, new HashSet<String>(tags) ) ;
Pair<Block,Block> result = new Pair<Block,Block>( block1, block2 ) ;
return result ;
}
}