/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdi.internal; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.jdi.internal.jdwp.JdwpArrayID; import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket; import org.eclipse.jdi.internal.jdwp.JdwpID; import org.eclipse.jdi.internal.jdwp.JdwpObjectID; import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.ArrayReference; import com.sun.jdi.ArrayType; import com.sun.jdi.ClassNotLoadedException; import com.sun.jdi.Field; import com.sun.jdi.Location; import com.sun.jdi.Method; import com.sun.jdi.ReferenceType; import com.sun.jdi.Type; import com.sun.jdi.Value; /** * this class implements the corresponding interfaces declared by the JDI * specification. See the com.sun.jdi package for more information. * */ public class ArrayTypeImpl extends ReferenceTypeImpl implements ArrayType { /** JDWP Tag. */ public static final byte typeTag = JdwpID.TYPE_TAG_ARRAY; /** component type */ private Type fComponentType; /** Component type name */ private String fComponentTypeName; /** * Creates new ArrayTypeImpl. * @param vmImpl the VM * @param arrayID the array ID */ public ArrayTypeImpl(VirtualMachineImpl vmImpl, JdwpArrayID arrayID) { super("ArrayType", vmImpl, arrayID); //$NON-NLS-1$ } /** * Creates new ArrayTypeImpl. * @param vmImpl the VM * @param arrayID the array ID * @param signature the array type signature * @param genericSignature the array type generic signature */ public ArrayTypeImpl(VirtualMachineImpl vmImpl, JdwpArrayID arrayID, String signature, String genericSignature) { super("ArrayType", vmImpl, arrayID, signature, genericSignature); //$NON-NLS-1$ } /** * @return Returns type tag. */ @Override public byte typeTag() { return typeTag; } /** * @return Create a null value instance of the type. */ @Override public Value createNullValue() { return new ArrayReferenceImpl(virtualMachineImpl(), new JdwpObjectID( virtualMachineImpl())); } /** * @return Returns the JNI signature of the components of this array class. */ @Override public String componentSignature() { return signature().substring(1); } /** * @return Returns the type of the array components. * @throws ClassNotLoadedException if the class has not been loaded */ @Override public Type componentType() throws ClassNotLoadedException { if (fComponentType == null) { fComponentType = TypeImpl.create(virtualMachineImpl(), componentSignature(), classLoader()); } return fComponentType; } /** * @return Returns a text representation of the component type. */ @Override public String componentTypeName() { if (fComponentTypeName == null) { fComponentTypeName = signatureToName(componentSignature()); } return fComponentTypeName; } /** * @param length the desired length of the new array * @return Creates and returns a new instance of this array class in the * target VM. */ @Override public ArrayReference newInstance(int length) { // Note that this information should not be cached. initJdwpRequest(); try { ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); DataOutputStream outData = new DataOutputStream(outBytes); write(this, outData); writeInt(length, "length", outData); //$NON-NLS-1$ JdwpReplyPacket replyPacket = requestVM( JdwpCommandPacket.AT_NEW_INSTANCE, outBytes); defaultReplyErrorHandler(replyPacket.errorCode()); DataInputStream replyData = replyPacket.dataInStream(); ArrayReferenceImpl arrayRef = (ArrayReferenceImpl) ObjectReferenceImpl .readObjectRefWithTag(this, replyData); return arrayRef; } catch (IOException e) { defaultIOExceptionHandler(e); return null; } finally { handledJdwpRequest(); } } /** * @return Returns a List filled with all Location objects that map to the * given line number. */ @Override public List<Location> locationsOfLine(int line) { // If this reference type is an ArrayType, the returned list is always // empty. return Collections.EMPTY_LIST; } /** * @param target the target * @param in the stream * @return Reads JDWP representation and returns new instance. * @throws IOException if the reading fails */ public static ArrayTypeImpl read(MirrorImpl target, DataInputStream in) throws IOException { VirtualMachineImpl vmImpl = target.virtualMachineImpl(); JdwpArrayID ID = new JdwpArrayID(vmImpl); ID.read(in); if (target.fVerboseWriter != null) target.fVerboseWriter.println("arrayType", ID.value()); //$NON-NLS-1$ if (ID.isNull()) return null; ArrayTypeImpl mirror = (ArrayTypeImpl) vmImpl.getCachedMirror(ID); if (mirror == null) { mirror = new ArrayTypeImpl(vmImpl, ID); vmImpl.addCachedMirror(mirror); } return mirror; } /** * @return Returns modifier bits. */ @Override public int modifiers() { return MODIFIER_ACC_PUBLIC | MODIFIER_ACC_FINAL; } /** * @return Returns a list containing each Field declared in this type. */ @Override public List<Field> fields() { return Collections.EMPTY_LIST; } /** * @return Returns a list containing each Method declared in this type. */ @Override public List<Method> methods() { return Collections.EMPTY_LIST; } /** * @return a Map of the requested static Field objects with their Value. */ @Override public Map<Field, Value> getValues(List<? extends Field> fields) { if (fields.isEmpty()) { return new HashMap<>(); } throw new IllegalArgumentException( JDIMessages.ArrayTypeImpl_getValues_not_allowed_on_array_1); } /** * @return Returns a List containing each ReferenceType declared within this * type. */ @Override public List<ReferenceType> nestedTypes() { return Collections.EMPTY_LIST; } /** * @return Returns status of class/interface. */ @Override protected int status() { return ReferenceTypeImpl.JDWP_CLASS_STATUS_INITIALIZED | ReferenceTypeImpl.JDWP_CLASS_STATUS_PREPARED | ReferenceTypeImpl.JDWP_CLASS_STATUS_VERIFIED; } /** * @param target the target * @param withGenericSignature if the generic signature should be read * @param in the stream * @return Reads JDWP representation and returns new instance. * @throws IOException if the read fails */ public static ArrayTypeImpl readWithSignature(MirrorImpl target, boolean withGenericSignature, DataInputStream in) throws IOException { VirtualMachineImpl vmImpl = target.virtualMachineImpl(); JdwpArrayID ID = new JdwpArrayID(vmImpl); ID.read(in); if (target.fVerboseWriter != null) target.fVerboseWriter.println("arrayType", ID.value()); //$NON-NLS-1$ String signature = target.readString("signature", in); //$NON-NLS-1$ String genericSignature = null; if (withGenericSignature) { genericSignature = target.readString("generic signature", in); //$NON-NLS-1$ } if (ID.isNull()) return null; ArrayTypeImpl mirror = (ArrayTypeImpl) vmImpl.getCachedMirror(ID); if (mirror == null) { mirror = new ArrayTypeImpl(vmImpl, ID); vmImpl.addCachedMirror(mirror); } mirror.setSignature(signature); mirror.setGenericSignature(genericSignature); return mirror; } /** * @see com.sun.jdi.ReferenceType#allLineLocations() */ @Override public List<Location> allLineLocations() { // If this reference type is an ArrayType, the returned list is always // empty. return Collections.EMPTY_LIST; } /** * @see com.sun.jdi.ReferenceType#allMethods() */ @Override public List<Method> allMethods() { return Collections.EMPTY_LIST; } /** * @see com.sun.jdi.ReferenceType#allFields() */ @Override public List<Field> allFields() { return Collections.EMPTY_LIST; } /** * @return Returns an identifying name for the source corresponding to the * declaration of this type. */ @Override public String sourceName() throws AbsentInformationException { throw new AbsentInformationException( JDIMessages.ArrayTypeImpl_No_source_name_for_Arrays_1); } /** * @see com.sun.jdi.ReferenceType#visibleFields() */ @Override public List<Field> visibleFields() { return Collections.EMPTY_LIST; } /** * @see com.sun.jdi.ReferenceType#visibleMethods() */ @Override public List<Method> visibleMethods() { return Collections.EMPTY_LIST; } /** * @see com.sun.jdi.ReferenceType#fieldByName(String) */ @Override public Field fieldByName(String arg1) { return null; } /** * @see com.sun.jdi.ReferenceType#methodsByName(String) */ @Override public List<Method> methodsByName(String arg1) { return Collections.EMPTY_LIST; } /** * @see com.sun.jdi.ReferenceType#methodsByName(String, String) */ @Override public List<Method> methodsByName(String arg1, String arg2) { return Collections.EMPTY_LIST; } }