/******************************************************************************* * Copyright (c) 1998, 2015 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 v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.classfile; import java.io.File; import org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClass; import org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClassDescription; import org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClassNotFoundException; import org.eclipse.persistence.tools.workbench.utility.ClassTools; import org.eclipse.persistence.tools.workbench.utility.classfile.ClassFile; import org.eclipse.persistence.tools.workbench.utility.string.StringTools; /** * Derive most of the type's state from the class name. * Build the external class only on demand. */ final class CFExternalClassDescription implements ExternalClassDescription { /** The name of the type. */ private final String name; /** The classpath entry that contains the class file corresponding to the type. */ private final File classpathEntry; /** The repository used by the description to find other descriptions. */ private final CFExternalClassRepository repository; /** The external class corresponding to the description. This is null until needed. */ private ExternalClass externalClass; // pseudo-final // ********** Constructors ********** /** * Package-accessible constructor. */ CFExternalClassDescription(String name, String classpathEntry, CFExternalClassRepository repository) { super(); this.name = name; this.classpathEntry = new File(classpathEntry); this.repository = repository; } /** * Package-accessible constructor. * Used for referenced types and "array" types that * do not have a classpath entry and should not ever * build an external class. */ CFExternalClassDescription(String name, CFExternalClassRepository repository) { super(); this.name = name; this.classpathEntry = null; this.repository = repository; } // ********** ExternalClassDescription implementation ********** /** * @see org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClassDescription#getArrayDepth() */ public int getArrayDepth() { return ClassTools.arrayDepthForClassNamed(this.name); } /** * @see org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ClassDescription#getAdditionalInfo() */ public String getAdditionalInfo() { return this.classpathEntry.getPath(); } /** * @see org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClassDescription#getElementTypeName() */ public String getElementTypeName() { return ClassTools.elementTypeNameForClassNamed(this.name); } /** * @see org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClassDescription#getExternalClass() */ public synchronized ExternalClass getExternalClass() throws ExternalClassNotFoundException { if (this.externalClass == null) { this.externalClass = this.buildExternalClass(); } return this.externalClass; } /** * @see org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ClassDescription#getName() */ public String getName() { return this.name; } /** * @see org.eclipse.persistence.tools.workbench.mappingsmodel.spi.meta.ExternalClassDescription#isSynthetic() */ public boolean isSynthetic() { return ClassTools.classNamedIsAnonymous(this.name); } // ********** standard methods ********** public String toString() { return StringTools.buildToStringFor(this, this.getName()); } // ********** package-accessible methods ********** ExternalClassDescription classDescriptionNamed(String className) { return this.repository.getClassDescriptionNamed(className); } // ********** internal methods ********** /** * Build an external class corresponding to the external class description. */ private ExternalClass buildExternalClass() throws ExternalClassNotFoundException { // external array *class descriptions* are supported; but we do *not* support external array *classes* if (this.classpathEntry == null) { throw new IllegalStateException(); } try { return new CFExternalClass(ClassFile.forClass(this.classpathEntry, this.name), this); } catch (Throwable t) { throw new ExternalClassNotFoundException(this.name, t); } } }