CPMember.java

  1. /*
  2.  *  Licensed to the Apache Software Foundation (ASF) under one or more
  3.  *  contributor license agreements.  See the NOTICE file distributed with
  4.  *  this work for additional information regarding copyright ownership.
  5.  *  The ASF licenses this file to You under the Apache License, Version 2.0
  6.  *  (the "License"); you may not use this file except in compliance with
  7.  *  the License.  You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.commons.compress.harmony.unpack200.bytecode;

  18. import java.io.DataOutputStream;
  19. import java.io.IOException;
  20. import java.util.Collections;
  21. import java.util.List;
  22. import java.util.Objects;

  23. /**
  24.  * Superclass for member constant pool entries, such as fields or methods.
  25.  */
  26. public class CPMember extends ClassFileEntry {

  27.     List<Attribute> attributes;
  28.     short flags;
  29.     CPUTF8 name;
  30.     transient int nameIndex;
  31.     protected final CPUTF8 descriptor;
  32.     transient int descriptorIndex;

  33.     /**
  34.      * Constructs a new CPMember.
  35.      *
  36.      * @param name       TODO
  37.      * @param descriptor TODO
  38.      * @param flags      TODO
  39.      * @param attributes TODO
  40.      * @throws NullPointerException if name or descriptor is null
  41.      */
  42.     public CPMember(final CPUTF8 name, final CPUTF8 descriptor, final long flags, final List<Attribute> attributes) {
  43.         this.name = Objects.requireNonNull(name, "name");
  44.         this.descriptor = Objects.requireNonNull(descriptor, "descriptor");
  45.         this.flags = (short) flags;
  46.         this.attributes = attributes == null ? Collections.EMPTY_LIST : attributes;
  47.     }

  48.     @Override
  49.     protected void doWrite(final DataOutputStream dos) throws IOException {
  50.         dos.writeShort(flags);
  51.         dos.writeShort(nameIndex);
  52.         dos.writeShort(descriptorIndex);
  53.         final int attributeCount = attributes.size();
  54.         dos.writeShort(attributeCount);
  55.         for (int i = 0; i < attributeCount; i++) {
  56.             final Attribute attribute = attributes.get(i);
  57.             attribute.doWrite(dos);
  58.         }
  59.     }

  60.     @Override
  61.     public boolean equals(final Object obj) {
  62.         if (this == obj) {
  63.             return true;
  64.         }
  65.         if (obj == null) {
  66.             return false;
  67.         }
  68.         if (getClass() != obj.getClass()) {
  69.             return false;
  70.         }
  71.         final CPMember other = (CPMember) obj;
  72.         return Objects.equals(attributes, other.attributes)
  73.                 && Objects.equals(descriptor, other.descriptor)
  74.                 && flags == other.flags
  75.                 && Objects.equals(name, other.name);
  76.     }

  77.     @Override
  78.     protected ClassFileEntry[] getNestedClassFileEntries() {
  79.         final int attributeCount = attributes.size();
  80.         final ClassFileEntry[] entries = new ClassFileEntry[attributeCount + 2];
  81.         entries[0] = name;
  82.         entries[1] = descriptor;
  83.         for (int i = 0; i < attributeCount; i++) {
  84.             entries[i + 2] = attributes.get(i);
  85.         }
  86.         return entries;
  87.     }

  88.     @Override
  89.     public int hashCode() {
  90.         final int PRIME = 31;
  91.         int result = 1;
  92.         result = PRIME * result + attributes.hashCode();
  93.         result = PRIME * result + descriptor.hashCode();
  94.         result = PRIME * result + flags;
  95.         result = PRIME * result + name.hashCode();
  96.         return result;
  97.     }

  98.     @Override
  99.     protected void resolve(final ClassConstantPool pool) {
  100.         super.resolve(pool);
  101.         nameIndex = pool.indexOf(name);
  102.         descriptorIndex = pool.indexOf(descriptor);
  103.         attributes.forEach(attribute -> attribute.resolve(pool));
  104.     }

  105.     @Override
  106.     public String toString() {
  107.         return "CPMember: " + name + "(" + descriptor + ")";
  108.     }

  109. }