package org.eclipse.jdt.internal.compiler.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings({"rawtypes", "unchecked"})
public class ManifestAnalyzer {
private static final int
START = 0,
= 1,
= 2,
SKIPPING_WHITESPACE = 3,
READING_JAR = 4,
CONTINUING = 5,
SKIP_LINE = 6;
private static final char[] =
"Class-Path:".toCharArray();
private int classpathSectionsCount;
private ArrayList calledFilesNames;
public boolean analyzeManifestContents(InputStream inputStream) throws IOException {
char[] chars = Util.getInputStreamAsCharArray(inputStream, -1, Util.UTF_8);
return analyzeManifestContents(chars);
}
public boolean analyzeManifestContents(char[] chars) {
int state = START, substate = 0;
StringBuffer currentJarToken = new StringBuffer();
int currentChar;
this.classpathSectionsCount = 0;
this.calledFilesNames = null;
for (int i = 0, max = chars.length; i < max;) {
currentChar = chars[i++];
if (currentChar == '\r') {
if (i < max) {
currentChar = chars[i++];
}
}
switch (state) {
case START:
if (currentChar == CLASSPATH_HEADER_TOKEN[0]) {
state = IN_CLASSPATH_HEADER;
substate = 1;
} else {
state = SKIP_LINE;
}
break;
case IN_CLASSPATH_HEADER:
if (currentChar == '\n') {
state = START;
} else if (currentChar != CLASSPATH_HEADER_TOKEN[substate++]) {
state = SKIP_LINE;
} else if (substate == CLASSPATH_HEADER_TOKEN.length) {
state = PAST_CLASSPATH_HEADER;
}
break;
case PAST_CLASSPATH_HEADER:
if (currentChar == ' ') {
state = SKIPPING_WHITESPACE;
this.classpathSectionsCount++;
} else {
return false;
}
break;
case SKIPPING_WHITESPACE:
if (currentChar == '\n') {
state = CONTINUING;
} else if (currentChar != ' ') {
currentJarToken.append((char) currentChar);
state = READING_JAR;
} else {
addCurrentTokenJarWhenNecessary(currentJarToken);
}
break;
case CONTINUING:
if (currentChar == '\n') {
addCurrentTokenJarWhenNecessary(currentJarToken);
state = START;
} else if (currentChar == ' ') {
state = SKIPPING_WHITESPACE;
} else if (currentChar == CLASSPATH_HEADER_TOKEN[0]) {
addCurrentTokenJarWhenNecessary(currentJarToken);
state = IN_CLASSPATH_HEADER;
substate = 1;
} else if (this.calledFilesNames == null) {
addCurrentTokenJarWhenNecessary(currentJarToken);
state = START;
} else {
addCurrentTokenJarWhenNecessary(currentJarToken);
state = SKIP_LINE;
}
break;
case SKIP_LINE:
if (currentChar == '\n') {
state = START;
}
break;
case READING_JAR:
if (currentChar == '\n') {
state = CONTINUING;
break;
} else if (currentChar == ' ') {
state = SKIPPING_WHITESPACE;
} else {
currentJarToken.append((char) currentChar);
break;
}
addCurrentTokenJarWhenNecessary(currentJarToken);
break;
}
}
switch (state) {
case START:
return true;
case IN_CLASSPATH_HEADER:
return true;
case PAST_CLASSPATH_HEADER:
return false;
case SKIPPING_WHITESPACE:
addCurrentTokenJarWhenNecessary(currentJarToken);
return true;
case CONTINUING:
addCurrentTokenJarWhenNecessary(currentJarToken);
return true;
case SKIP_LINE:
if (this.classpathSectionsCount != 0) {
if (this.calledFilesNames == null) {
return false;
}
}
return true;
case READING_JAR:
return false;
}
return true;
}
private boolean addCurrentTokenJarWhenNecessary(StringBuffer currentJarToken) {
if (currentJarToken != null && currentJarToken.length() > 0) {
if (this.calledFilesNames == null) {
this.calledFilesNames = new ArrayList();
}
this.calledFilesNames.add(currentJarToken.toString());
currentJarToken.setLength(0);
return true;
}
return false;
}
public int getClasspathSectionsCount() {
return this.classpathSectionsCount;
}
public List getCalledFileNames() {
return this.calledFilesNames;
}
}