| /* |
| * 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.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, String typeId) { |
| return new StandardSymbolData(className, null, null, uriString, lineNumber, |
| typeId); |
| } |
| |
| public static StandardSymbolData forMember(String className, |
| String memberName, String methodSig, String uriString, int lineNumber) { |
| return new StandardSymbolData(className, memberName, methodSig, uriString, |
| lineNumber, 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 int fragmentNumber = -1; |
| private String memberName; |
| private String methodSig; |
| private int sourceLine; |
| private String sourceUri; |
| private String symbolName; |
| private String typeId; |
| |
| private StandardSymbolData(String className, String memberName, |
| String methodSig, String sourceUri, int sourceLine, String typeId) { |
| 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.typeId = typeId; |
| } |
| |
| @Override |
| public String getClassName() { |
| return className; |
| } |
| |
| @Override |
| public int getFragmentNumber() { |
| return fragmentNumber; |
| } |
| |
| @Override |
| public String getJsniIdent() { |
| if (memberName == null) { |
| return null; |
| } |
| if (methodSig == null) { |
| return className + "::" + memberName; |
| } |
| return className + "::" + memberName + methodSig; |
| } |
| |
| @Override |
| public String getMemberName() { |
| return memberName; |
| } |
| @Override |
| public String getRuntimeTypeId() { |
| return typeId; |
| } |
| |
| @Override |
| public int getSourceLine() { |
| return sourceLine; |
| } |
| |
| @Override |
| public String getSourceUri() { |
| return sourceUri; |
| } |
| |
| @Override |
| public String getSymbolName() { |
| return symbolName; |
| } |
| |
| @Override |
| public boolean isClass() { |
| return memberName == null; |
| } |
| |
| @Override |
| public boolean isField() { |
| return memberName != null && methodSig == null; |
| } |
| |
| @Override |
| public boolean isMethod() { |
| return methodSig != null; |
| } |
| |
| public void setFragmentNumber(int fragNum) { |
| fragmentNumber = fragNum; |
| } |
| |
| 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(); |
| typeId = (String) in.readObject(); |
| fragmentNumber = in.readInt(); |
| } |
| |
| /** |
| * 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.writeObject(typeId); |
| out.writeInt(fragmentNumber); |
| } |
| |
| } |