CPMember.java

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

  20. import java.io.DataOutputStream;
  21. import java.io.IOException;
  22. import java.util.Collections;
  23. import java.util.List;
  24. import java.util.Objects;

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

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

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

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

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

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

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

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

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

  108. }