Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.hk2.utilities;
import java.io.BufferedReader;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Singleton;
import org.glassfish.hk2.api.ClassAnalyzer;
import org.glassfish.hk2.api.Descriptor;
import org.glassfish.hk2.api.DescriptorType;
import org.glassfish.hk2.api.DescriptorVisibility;
import org.glassfish.hk2.api.HK2Loader;
import org.glassfish.hk2.api.PerLookup;
import org.glassfish.hk2.utilities.general.GeneralUtilities;
import org.glassfish.hk2.utilities.reflection.ReflectionHelper;
/**
* The implementation of the descriptor itself, with the
* bonus of being externalizable, and having writeable fields
*
* @author jwells
*/
public class DescriptorImpl implements Descriptor, Externalizable {
/**
* For serialization
*/
private static final long serialVersionUID = 1558442492395467828L;
private final static String CONTRACT_KEY = "contract=";
private final static String NAME_KEY = "name=";
private final static String SCOPE_KEY = "scope=";
private final static String QUALIFIER_KEY = "qualifier=";
private final static String TYPE_KEY = "type=";
private final static String VISIBILITY_KEY = "visibility=";
private final static String METADATA_KEY = "metadata=";
private final static String RANKING_KEY = "rank=";
private final static String PROXIABLE_KEY = "proxiable=";
private final static String PROXY_FOR_SAME_SCOPE_KEY = "proxyForSameScope=";
private final static String ANALYSIS_KEY = "analysis=";
private final static String PROVIDE_METHOD_DT = "PROVIDE";
private final static String LOCAL_DT = "LOCAL";
private final static String START_START = "[";
private final static String END_START = "]";
private final static char END_START_CHAR = ']';
private final static String SINGLETON_DIRECTIVE = "S";
private final static String NOT_IN_CONTRACTS_DIRECTIVE = "-";
private final static char SINGLETON_DIRECTIVE_CHAR = 'S';
private final static char NOT_IN_CONTRACTS_DIRECTIVE_CHAR = '-';
private final static Set EMPTY_CONTRACTS_SET = Collections.emptySet();
private final static Set EMPTY_QUALIFIER_SET = Collections.emptySet();
private final static Map> EMPTY_METADATAS_MAP = Collections.emptyMap();
private Set contracts;
private String implementation;
private String name;
private String scope = PerLookup.class.getName();
private Map> metadatas;
private Set qualifiers;
private DescriptorType descriptorType = DescriptorType.CLASS;
private DescriptorVisibility descriptorVisibility = DescriptorVisibility.NORMAL;
private transient HK2Loader loader;
private int rank;
private Boolean proxiable;
private Boolean proxyForSameScope;
private String analysisName;
private Long id;
private Long locatorId;
/**
* For serialization
*/
public DescriptorImpl() {
}
/**
* Does a deep copy of the incoming descriptor
*
* @param copyMe The descriptor to copy
*/
public DescriptorImpl(Descriptor copyMe) {
name = copyMe.getName();
scope = copyMe.getScope();
implementation = copyMe.getImplementation();
descriptorType = copyMe.getDescriptorType();
descriptorVisibility = copyMe.getDescriptorVisibility();
loader = copyMe.getLoader();
rank = copyMe.getRanking();
proxiable = copyMe.isProxiable();
proxyForSameScope = copyMe.isProxyForSameScope();
id = copyMe.getServiceId();
locatorId = copyMe.getLocatorId();
analysisName = copyMe.getClassAnalysisName();
if (copyMe.getAdvertisedContracts() != null && !copyMe.getAdvertisedContracts().isEmpty()) {
contracts = new LinkedHashSet();
contracts.addAll(copyMe.getAdvertisedContracts());
}
if (copyMe.getQualifiers() != null && !copyMe.getQualifiers().isEmpty()) {
qualifiers = new LinkedHashSet();
qualifiers.addAll(copyMe.getQualifiers());
}
if (copyMe.getMetadata() != null && !copyMe.getMetadata().isEmpty()) {
metadatas = new LinkedHashMap>();
metadatas.putAll(ReflectionHelper.deepCopyMetadata(copyMe.getMetadata()));
}
}
/**
* This creates this descriptor impl, taking all of the fields
* as given
*
* @param contracts The set of contracts this descriptor impl should advertise (should not be null)
* @param name The name of this descriptor (may be null)
* @param scope The scope of this descriptor. If null PerLookup is assumed
* @param implementation The name of the implementation class (should not be null)
* @param metadatas The metadata associated with this descriptor (should not be null)
* @param qualifiers The set of qualifiers associated with this descriptor (should not be null)
* @param descriptorType The type of this descriptor (should not be null)
* @param descriptorVisibility The visibility this descriptor should have
* @param loader The HK2Loader to associated with this descriptor (may be null)
* @param rank The rank to initially associate with this descriptor
* @param proxiable The proxiable value to associate with this descriptor (may be null)
* @param proxyForSameScope The proxyForSameScope value to associate with this descriptor (may be null)
* @param analysisName The name of the ClassAnalysis service to use
* @param id The ID this descriptor should take (may be null)
* @param locatorId The locator ID this descriptor should take (may be null)
*/
public DescriptorImpl(
Set contracts,
String name,
String scope,
String implementation,
Map> metadatas,
Set qualifiers,
DescriptorType descriptorType,
DescriptorVisibility descriptorVisibility,
HK2Loader loader,
int rank,
Boolean proxiable,
Boolean proxyForSameScope,
String analysisName,
Long id,
Long locatorId) {
if (contracts != null && !contracts.isEmpty()) {
this.contracts = new LinkedHashSet();
this.contracts.addAll(contracts);
}
this.implementation = implementation;
this.name = name;
this.scope = scope;
if (metadatas != null && !metadatas.isEmpty()) {
this.metadatas = new LinkedHashMap>();
this.metadatas.putAll(ReflectionHelper.deepCopyMetadata(metadatas));
}
if (qualifiers != null && !qualifiers.isEmpty()) {
this.qualifiers = new LinkedHashSet();
this.qualifiers.addAll(qualifiers);
}
this.descriptorType = descriptorType;
this.descriptorVisibility = descriptorVisibility;
this.id = id;
this.rank = rank;
this.proxiable = proxiable;
this.proxyForSameScope = proxyForSameScope;
this.analysisName = analysisName;
this.locatorId = locatorId;
this.loader = loader;
}
@Override
public synchronized Set getAdvertisedContracts() {
if (contracts == null) return EMPTY_CONTRACTS_SET;
return Collections.unmodifiableSet(contracts);
}
/**
* Adds an advertised contract to the set of contracts advertised by this descriptor
* @param addMe The contract to add. May not be null
*/
public synchronized void addAdvertisedContract(String addMe) {
if (addMe == null) return;
if (contracts == null) contracts = new LinkedHashSet();
contracts.add(addMe);
}
/**
* Removes an advertised contract from the set of contracts advertised by this descriptor
* @param removeMe The contract to remove. May not be null
* @return true if removeMe was removed from the set
*/
public synchronized boolean removeAdvertisedContract(String removeMe) {
if (removeMe == null || contracts == null) return false;
return contracts.remove(removeMe);
}
@Override
public synchronized String getImplementation() {
return implementation;
}
/**
* Sets the implementation
* @param implementation The implementation this descriptor should have
*/
public synchronized void setImplementation(String implementation) {
this.implementation = implementation;
}
@Override
public synchronized String getScope() {
return scope;
}
/**
* Sets the scope this descriptor should have
* @param scope The scope of this descriptor
*/
public synchronized void setScope(String scope) {
this.scope = scope;
}
@Override
public synchronized String getName() {
return name;
}
/**
* Sets the name this descriptor should have
* @param name The name for this descriptor
*/
public synchronized void setName(String name) {
this.name = name;
}
@Override
public synchronized Set getQualifiers() {
if (qualifiers == null) return EMPTY_QUALIFIER_SET;
return Collections.unmodifiableSet(qualifiers);
}
/**
* Adds the given string to the list of qualifiers
*
* @param addMe The fully qualified class name of the qualifier to add. May not be null
*/
public synchronized void addQualifier(String addMe) {
if (addMe == null) return;
if (qualifiers == null) qualifiers = new LinkedHashSet();
qualifiers.add(addMe);
}
/**
* Removes the given qualifier from the list of qualifiers
*
* @param removeMe The fully qualifier class name of the qualifier to remove. May not be null
* @return true if the given qualifier was removed
*/
public synchronized boolean removeQualifier(String removeMe) {
if (removeMe == null) return false;
if (qualifiers == null) return false;
return qualifiers.remove(removeMe);
}
@Override
public synchronized DescriptorType getDescriptorType() {
return descriptorType;
}
/**
* Sets the descriptor type
* @param descriptorType The descriptor type. May not be null
*/
public synchronized void setDescriptorType(DescriptorType descriptorType) {
if (descriptorType == null) throw new IllegalArgumentException();
this.descriptorType = descriptorType;
}
@Override
public synchronized DescriptorVisibility getDescriptorVisibility() {
return descriptorVisibility;
}
/**
* Sets the descriptor visilibity
* @param descriptorVisibility The visibility this descriptor should have
*/
public synchronized void setDescriptorVisibility(DescriptorVisibility descriptorVisibility) {
if (descriptorVisibility == null) throw new IllegalArgumentException();
this.descriptorVisibility = descriptorVisibility;
}
@Override
public synchronized Map> getMetadata() {
if (metadatas == null) return EMPTY_METADATAS_MAP;
return Collections.unmodifiableMap(metadatas);
}
/**
* Sets the metadata of this DescriptorImpl to exactly the set
* of metadata in the incoming map. Any previous metadata values
* will be removed. A deep copy of the incoming map will be made,
* so it is safe to use the input map after use of this API
*
* @param metadata The non-null metadata that this descriptor
* should have
*/
public synchronized void setMetadata(Map> metadata) {
if (metadatas == null) {
metadatas = new LinkedHashMap>();
}
else {
metadatas.clear();
}
metadatas.putAll(ReflectionHelper.deepCopyMetadata(metadata));
}
/**
* Adds all of the entries from this map to the existing descriptor's
* metadata. None of the keys in the map may have the '=' character
*
* @param metadata The non-null but possibly empty list of fields
* to add to the metadata map
*/
public synchronized void addMetadata(Map> metadata) {
if (metadatas == null) metadatas = new LinkedHashMap>();
metadatas.putAll(ReflectionHelper.deepCopyMetadata(metadata));
}
/**
* Adds a value to the list of values associated with this key
*
* @param key The key to which to add the value. May not be null. May
* not contain the character '='
* @param value The value to add. May not be null
*/
public synchronized void addMetadata(String key, String value) {
if (metadatas == null) metadatas = new LinkedHashMap>();
ReflectionHelper.addMetadata(metadatas, key, value);
}
/**
* Removes the given value from the given key
*
* @param key The key of the value to remove. May not be null, and
* may not contain the character '='
* @param value The value to remove. May not be null
* @return true if the value was removed
*/
public synchronized boolean removeMetadata(String key, String value) {
if (metadatas == null) return false;
return ReflectionHelper.removeMetadata(metadatas, key, value);
}
/**
* Removes all the metadata values associated with key
*
* @param key The key of the metadata values to remove
* @return true if any value was removed
*/
public synchronized boolean removeAllMetadata(String key) {
if (metadatas == null) return false;
return ReflectionHelper.removeAllMetadata(metadatas, key);
}
/**
* Removes all metadata values
*/
public synchronized void clearMetadata() {
metadatas = null;
}
/* (non-Javadoc)
* @see org.glassfish.hk2.api.Descriptor#getLoader()
*/
@Override
public synchronized HK2Loader getLoader() {
return loader;
}
/**
* Sets the loader to use with this descriptor
* @param loader The loader to use with this descriptor
*/
public synchronized void setLoader(HK2Loader loader) {
this.loader = loader;
}
@Override
public synchronized int getRanking() {
return rank;
}
/* (non-Javadoc)
* @see org.glassfish.hk2.api.Descriptor#setRanking(int)
*/
@Override
public synchronized int setRanking(int ranking) {
int retVal = rank;
rank = ranking;
return retVal;
}
@Override
public synchronized Long getServiceId() {
return id;
}
/**
* Sets the service id for this descriptor
* @param id the service id for this descriptor
*/
public synchronized void setServiceId(Long id) {
this.id = id;
}
@Override
public Boolean isProxiable() {
return proxiable;
}
/**
* Sets whether or not this descriptor should be proxied
* @param proxiable if true then this descriptor will be proxied.
* If false then this descriptor will not be proxied. If null
* this descriptor will follow the rules of the scope it is in
*/
public void setProxiable(Boolean proxiable) {
this.proxiable = proxiable;
}
@Override
public Boolean isProxyForSameScope() {
return proxyForSameScope;
}
/**
* Sets whether or not to proxy this descriptor for other
* services in the same scope
*
* @param proxyForSameScope if true then this descriptor will be proxied
* for services in the same scope. If false then this descriptor will not
* be proxied for services in the same scope. If null
* this descriptor will follow the rules of the scope it is in
*/
public void setProxyForSameScope(Boolean proxyForSameScope) {
this.proxyForSameScope = proxyForSameScope;
}
@Override
public String getClassAnalysisName() {
return analysisName;
}
/**
* Sets the name of the service that will be used
* to analyze this class
*
* @param name The name of the {@link ClassAnalyzer}
* service that should be used to analyze this
* descriptor
*/
public void setClassAnalysisName(String name) {
analysisName = name;
}
@Override
public synchronized Long getLocatorId() {
return locatorId;
}
/**
* Sets the locator id for this descriptor
* @param locatorId the locator id for this descriptor
*/
public synchronized void setLocatorId(Long locatorId) {
this.locatorId = locatorId;
}
public int hashCode() {
int retVal = 0;
if (implementation != null) {
retVal ^= implementation.hashCode();
}
if (contracts != null) {
for (String contract : contracts) {
retVal ^= contract.hashCode();
}
}
if (name != null) {
retVal ^= name.hashCode();
}
if (scope != null) {
retVal ^= scope.hashCode();
}
if (qualifiers != null) {
for (String qualifier : qualifiers) {
retVal ^= qualifier.hashCode();
}
}
if (descriptorType != null) {
retVal ^= descriptorType.hashCode();
}
if (descriptorVisibility != null) {
retVal ^= descriptorVisibility.hashCode();
}
if (metadatas != null) {
for (Map.Entry> entries : metadatas.entrySet()) {
retVal ^= entries.getKey().hashCode();
for (String value : entries.getValue()) {
retVal ^= value.hashCode();
}
}
}
if (proxiable != null) {
if (proxiable.booleanValue()) {
retVal ^= 1;
}
else {
retVal ^= -1;
}
}
if (proxyForSameScope != null) {
if (proxyForSameScope.booleanValue()) {
retVal ^= 2;
}
else {
retVal ^= -2;
}
}
if (analysisName != null) {
retVal ^= analysisName.hashCode();
}
return retVal;
}
private static boolean equalOrderedCollection(Collection a, Collection b) {
if (a == b) return true;
if (a == null) return false;
if (b == null) return false;
if (a.size() != b.size()) return false;
Object aAsArray[] = a.toArray();
Object bAsArray[] = b.toArray();
for (int lcv = 0; lcv < a.size(); lcv++) {
if (!GeneralUtilities.safeEquals(aAsArray[lcv], bAsArray[lcv])) return false;
}
return true;
}
private static boolean equalMetadata(Map> a, Map> b) {
if (a == b) return true;
if (a == null) return false;
if (b == null) return false;
if (a.size() != b.size()) return false;
for (Map.Entry> entry : a.entrySet()) {
String aKey = entry.getKey();
List aValue = entry.getValue();
List bValue = b.get(aKey);
if (bValue == null) return false;
if (!equalOrderedCollection(aValue, bValue)) return false;
}
return true;
}
/**
* Tests if two descriptors are equal not taking into account the locator-id
* and server-id by comparing the following fields:
*
*
implementation
*
contracts
*
name
*
scope
*
qualifiers
*
descriptorType
*
descriptorVisibility
*
metadata
*
proxiable
*
proxyForSameScope
*
analysisName
*
*
* @param a The possibly null descriptor to compare
* @param b The possibly null descriptor to compare
* @return true if they are the same, false otherwise
*/
public static boolean descriptorEquals(Descriptor a, Descriptor b) {
if (a == null && b == null) return true;
if (a == null || b == null) return false;
if (!GeneralUtilities.safeEquals(a.getImplementation(), b.getImplementation())) return false;
if (!equalOrderedCollection(a.getAdvertisedContracts(), b.getAdvertisedContracts())) return false;
if (!GeneralUtilities.safeEquals(a.getName(), b.getName())) return false;
if (!GeneralUtilities.safeEquals(a.getScope(), b.getScope())) return false;
if (!equalOrderedCollection(a.getQualifiers(), b.getQualifiers())) return false;
if (!GeneralUtilities.safeEquals(a.getDescriptorType(), b.getDescriptorType())) return false;
if (!GeneralUtilities.safeEquals(a.getDescriptorVisibility(), b.getDescriptorVisibility())) return false;
if (!equalMetadata(a.getMetadata(), b.getMetadata())) return false;
if (!GeneralUtilities.safeEquals(a.isProxiable(), b.isProxiable())) return false;
if (!GeneralUtilities.safeEquals(a.isProxyForSameScope(), b.isProxyForSameScope())) return false;
if (!GeneralUtilities.safeEquals(a.getClassAnalysisName(), b.getClassAnalysisName())) return false;
return true;
}
/**
* This equals matches only if the following fields of the descriptor match:
*
*
implementation
*
contracts
*
name
*
scope
*
qualifiers
*
descriptorType
*
descriptorVisibility
*
metadata
*
proxiable
*
proxyForSameScope
*
analysisName
*
* @param a The object to compare to this one. May be null (which will result in a false)
* @return true if the descriptors are equal
*/
public boolean equals(Object a) {
if (a == null) return false;
if (!(a instanceof Descriptor)) return false;
Descriptor d = (Descriptor) a;
return descriptorEquals(this, d);
}
/**
* Will pretty print a descriptor
*
* @param sb The string buffer put the pretty print into
* @param d The descriptor to write
*/
public static void pretty(StringBuffer sb, Descriptor d) {
if (sb == null || d == null) return;
sb.append("\n\timplementation=" + d.getImplementation());
if (d.getName() != null) {
sb.append("\n\tname=" + d.getName());
}
sb.append("\n\tcontracts=");
sb.append(ReflectionHelper.writeSet(d.getAdvertisedContracts()));
sb.append("\n\tscope=" + d.getScope());
sb.append("\n\tqualifiers=");
sb.append(ReflectionHelper.writeSet(d.getQualifiers()));
sb.append("\n\tdescriptorType=" + d.getDescriptorType());
sb.append("\n\tdescriptorVisibility=" + d.getDescriptorVisibility());
sb.append("\n\tmetadata=");
sb.append(ReflectionHelper.writeMetadata(d.getMetadata()));
sb.append("\n\trank=" + d.getRanking());
sb.append("\n\tloader=" + d.getLoader());
sb.append("\n\tproxiable=" + d.isProxiable());
sb.append("\n\tproxyForSameScope=" + d.isProxyForSameScope());
sb.append("\n\tanalysisName=" + d.getClassAnalysisName());
sb.append("\n\tid=" + d.getServiceId());
sb.append("\n\tlocatorId=" + d.getLocatorId());
sb.append("\n\tidentityHashCode=" + System.identityHashCode(d));
}
public synchronized String toString() {
StringBuffer sb = new StringBuffer("Descriptor(");
pretty(sb, this);
sb.append(")");
return sb.toString();
}
/**
* This writes this object to the data output stream in a human-readable
* format, excellent for writing out data files
*
* @param out The output stream to write this object out to
* @throws IOException on failure
*/
public void writeObject(PrintWriter out) throws IOException {
out.print(START_START);
// Implementation
if (implementation != null) {
out.print(implementation);
}
out.print(END_START);
if (scope != null && scope.equals(Singleton.class.getName())) {
out.print(SINGLETON_DIRECTIVE);
}
boolean implementationInContracts = true;
if (contracts != null && implementation != null && !contracts.contains(implementation)) {
out.print(NOT_IN_CONTRACTS_DIRECTIVE);
implementationInContracts = false;
}
out.println();
// Contracts
if (contracts != null && !contracts.isEmpty() &&
(!implementationInContracts || (contracts.size() > 1))) {
String excluded = (implementationInContracts) ? implementation : null ;
out.println(CONTRACT_KEY + ReflectionHelper.writeSet(contracts, excluded));
}
if (name != null) {
out.println(NAME_KEY + name);
}
if ((scope != null) && !(
scope.equals(PerLookup.class.getName()) ||
scope.equals(Singleton.class.getName()))) {
out.println(SCOPE_KEY + scope);
}
if (qualifiers != null && !qualifiers.isEmpty()) {
out.println(QUALIFIER_KEY + ReflectionHelper.writeSet(qualifiers));
}
if (descriptorType != null && descriptorType.equals(DescriptorType.PROVIDE_METHOD)) {
out.println(TYPE_KEY + PROVIDE_METHOD_DT);
}
if (descriptorVisibility != null && descriptorVisibility.equals(DescriptorVisibility.LOCAL)) {
out.println(VISIBILITY_KEY + LOCAL_DT);
}
if (rank != 0) {
out.println(RANKING_KEY + rank);
}
if (proxiable != null) {
out.println(PROXIABLE_KEY + proxiable.booleanValue());
}
if (proxyForSameScope != null) {
out.println(PROXY_FOR_SAME_SCOPE_KEY + proxyForSameScope.booleanValue());
}
if (analysisName != null &&
!ClassAnalyzer.DEFAULT_IMPLEMENTATION_NAME.equals(analysisName)) {
out.println(ANALYSIS_KEY + analysisName);
}
if (metadatas != null && !metadatas.isEmpty()) {
out.println(METADATA_KEY + ReflectionHelper.writeMetadata(metadatas));
}
out.println(); // This demarks the end of the section
}
private void reinitialize() {
contracts = null;
implementation = null;
name = null;
scope = PerLookup.class.getName();
metadatas = null;
qualifiers = null;
descriptorType = DescriptorType.CLASS;
descriptorVisibility = DescriptorVisibility.NORMAL;
loader = null;
rank = 0;
proxiable = null;
proxyForSameScope = null;
analysisName = null;
id = null;
locatorId = null;
}
/**
* This can be used to read in instances of this object that were previously written out with
* writeObject. Useful for reading from external data files
*
* @param in The reader to read from
* @return true if a descriptor was read, false otherwise. This is useful if reading a file that might have comments at the end
* @throws IOException on failure
*/
public boolean readObject(BufferedReader in) throws IOException {
// Reinitialize all fields
reinitialize();
String line = in.readLine();
boolean sectionStarted = false;
while (line != null) {
String trimmed = line.trim();
if (!sectionStarted) {
if (trimmed.startsWith(START_START)) {
sectionStarted = true;
int endStartIndex = trimmed.indexOf(END_START_CHAR, 1);
if (endStartIndex < 0) {
throw new IOException("Start of implementation ends without ] character: " +
trimmed);
}
if (endStartIndex > 1) {
implementation = trimmed.substring(1, endStartIndex);
}
String directives = trimmed.substring(endStartIndex + 1);
boolean doesNotContainImplementation = false;
if (directives != null) {
for (int lcv = 0; lcv < directives.length(); lcv++) {
char charAt = directives.charAt(lcv);
if (charAt == SINGLETON_DIRECTIVE_CHAR) {
scope = Singleton.class.getName();
}
else if (charAt == NOT_IN_CONTRACTS_DIRECTIVE_CHAR) {
doesNotContainImplementation = true;
}
}
}
if (!doesNotContainImplementation && (implementation != null)) {
if (contracts == null) contracts = new LinkedHashSet();
contracts.add(implementation);
}
}
}
else {
if (trimmed.length() <= 0) {
// A blank line indicates end of object
return true;
}
int equalsIndex = trimmed.indexOf('=');
if (equalsIndex >= 1) {
String leftHandSide = trimmed.substring(0, equalsIndex + 1); // include the =
String rightHandSide = trimmed.substring(equalsIndex + 1);
if (leftHandSide.equalsIgnoreCase(CONTRACT_KEY)) {
if (contracts == null) contracts = new LinkedHashSet();
ReflectionHelper.readSet(rightHandSide, contracts);
}
else if (leftHandSide.equals(QUALIFIER_KEY)) {
LinkedHashSet localQualifiers = new LinkedHashSet();
ReflectionHelper.readSet(rightHandSide, localQualifiers);
if (!localQualifiers.isEmpty()) qualifiers = localQualifiers;
}
else if (leftHandSide.equals(NAME_KEY)) {
name = rightHandSide;
}
else if (leftHandSide.equals(SCOPE_KEY)) {
scope = rightHandSide;
}
else if (leftHandSide.equals(TYPE_KEY)) {
if (rightHandSide.equals(PROVIDE_METHOD_DT)) {
descriptorType = DescriptorType.PROVIDE_METHOD;
}
}
else if (leftHandSide.equals(VISIBILITY_KEY)) {
if (rightHandSide.equals(LOCAL_DT)) {
descriptorVisibility = DescriptorVisibility.LOCAL;
}
}
else if (leftHandSide.equals(METADATA_KEY)) {
LinkedHashMap> localMetadatas = new LinkedHashMap>();
ReflectionHelper.readMetadataMap(rightHandSide, localMetadatas);
if (!localMetadatas.isEmpty()) metadatas = localMetadatas;
}
else if (leftHandSide.equals(RANKING_KEY)) {
rank = Integer.parseInt(rightHandSide);
}
else if (leftHandSide.equals(PROXIABLE_KEY)) {
proxiable = Boolean.parseBoolean(rightHandSide);
}
else if (leftHandSide.equals(PROXY_FOR_SAME_SCOPE_KEY)) {
proxyForSameScope = Boolean.parseBoolean(rightHandSide);
}
else if (leftHandSide.equals(ANALYSIS_KEY)) {
analysisName = rightHandSide;
}
// Otherwise it is an unknown type, just forget it
}
}
line = in.readLine();
}
return sectionStarted;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
StringWriter sw = new StringWriter();
writeObject(new PrintWriter(sw));
out.writeObject(sw.toString());
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
String descriptorString = (String) in.readObject();
readObject(new BufferedReader( new StringReader(descriptorString)));
}
}