blob: fc57185dca0fedcee3dffb30df51502bdda86d04 [file] [log] [blame]
/*
* Copyright 2009 Google Inc.
*
* 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 com.google.gwt.core.ext.linker.impl;
import com.google.gwt.core.ext.linker.CastableTypeMap;
import com.google.gwt.core.ext.linker.SymbolData;
import java.io.File;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URI;
import java.net.URISyntaxException;
/**
* An immutable implementation of SymbolData.
*/
public class StandardSymbolData implements SymbolData {
public static StandardSymbolData forClass(String className, String uriString,
int lineNumber, int queryId, CastableTypeMap castableTypeMap) {
return new StandardSymbolData(className, null, null, uriString, lineNumber,
queryId, castableTypeMap);
}
public static StandardSymbolData forMember(String className,
String memberName, String methodSig, String uriString, int lineNumber) {
return new StandardSymbolData(className, memberName, methodSig, uriString,
lineNumber, 0, null);
}
public static String toUriString(String fileName) {
File f = new File(fileName);
if (f.exists()) {
return f.toURI().toASCIIString();
} else {
try {
return new URI(fileName).toASCIIString();
} catch (URISyntaxException e) {
return null;
}
}
}
private String className;
private String memberName;
private String methodSig;
private int sourceLine;
private String sourceUri;
private String symbolName;
private int queryId;
private CastableTypeMap castableTypeMap;
private StandardSymbolData(String className, String memberName,
String methodSig, String sourceUri, int sourceLine, int queryId,
CastableTypeMap castableTypeMap) {
assert className != null && className.length() > 0 : "className";
assert memberName != null || methodSig == null : "methodSig without memberName";
assert sourceLine >= -1 : "sourceLine: " + sourceLine;
this.className = className;
this.memberName = memberName;
this.methodSig = methodSig;
this.sourceUri = sourceUri;
this.sourceLine = sourceLine;
this.queryId = queryId;
this.castableTypeMap = castableTypeMap;
}
public CastableTypeMap getCastableTypeMap() {
return castableTypeMap;
}
public String getClassName() {
return className;
}
public String getJsniIdent() {
if (memberName == null) {
return null;
}
if (methodSig == null) {
return className + "::" + memberName;
}
return className + "::" + memberName + methodSig;
}
public String getMemberName() {
return memberName;
}
public int getQueryId() {
return queryId;
}
public int getSourceLine() {
return sourceLine;
}
public String getSourceUri() {
return sourceUri;
}
public String getSymbolName() {
return symbolName;
}
public boolean isClass() {
return memberName == null;
}
public boolean isField() {
return memberName != null && methodSig == null;
}
public boolean isMethod() {
return methodSig != null;
}
public void setSymbolName(String symbolName) {
this.symbolName = symbolName;
}
@Override
public String toString() {
return isClass() ? className : getJsniIdent();
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
className = (String) in.readObject();
switch (in.read()) {
case 0:
break;
case 1:
memberName = in.readUTF();
break;
case 2:
memberName = in.readUTF();
methodSig = in.readUTF();
break;
default:
throw new InvalidObjectException("Unexpected input");
}
sourceLine = in.readInt();
sourceUri = (String) in.readObject();
symbolName = in.readUTF();
queryId = in.readInt();
castableTypeMap = (CastableTypeMap) in.readObject();
}
/**
* Implemented by hand for speed (over using reflection) because there are so
* many of these. Note that {@link #className} and {@link #sourceUri} are done
* as writeObject because the actual String instances are very likely to be
* shared among many instances of this class, so the same objects can be
* reused in the stream. The other String fields are done as UTF because it's
* slightly faster and the String objects are unlikely to be shared among
* instances.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeObject(className);
if (isClass()) {
out.write(0);
} else if (isField()) {
out.write(1);
out.writeUTF(memberName);
} else {
out.write(2);
out.writeUTF(memberName);
out.writeUTF(methodSig);
}
out.writeInt(sourceLine);
out.writeObject(sourceUri);
out.writeUTF(symbolName);
out.writeInt(queryId);
out.writeObject(castableTypeMap);
}
}