All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.microbean.bean.Id Maven / Gradle / Ivy

/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
 *
 * Copyright © 2023–2024 microBean™.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.microbean.bean;

import java.lang.constant.Constable;
import java.lang.constant.DynamicConstantDesc;
import java.lang.constant.MethodHandleDesc;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import javax.lang.model.type.TypeMirror;

import org.microbean.constant.Constables;

import org.microbean.qualifier.NamedAttributeMap;

import org.microbean.scope.ScopeMember;

import static java.lang.constant.ConstantDescs.BSM_INVOKE;
import static java.lang.constant.ConstantDescs.CD_boolean;
import static java.lang.constant.ConstantDescs.CD_int;
import static java.lang.constant.ConstantDescs.CD_List;
import static java.lang.constant.ConstantDescs.FALSE;
import static java.lang.constant.ConstantDescs.TRUE;

import static org.microbean.bean.BeanTypes.legalBeanType;
import static org.microbean.bean.ConstantDescs.CD_Id;

import static org.microbean.qualifier.ConstantDescs.CD_NamedAttributeMap;

public final record Id(List types,
                       List> attributes,
                       NamedAttributeMap governingScopeId,
                       boolean alternate,
                       int rank)
  implements Constable, Ranked, ScopeMember {

  public Id(final List types,
            final List> attributes,
            final NamedAttributeMap governingScopeId) {
    this(types, attributes, governingScopeId, false, Ranked.DEFAULT_RANK);
  }

  public Id(final List types,
            final List> attributes,
            final NamedAttributeMap governingScopeId,
            final int rank) {
    this(types, attributes, governingScopeId, false, rank);
  }

  public Id {
    // The code below jumps through some hoops to avoid copying the types list if possible.
    final int size = types.size();
    if (size == 0) {
      throw new IllegalArgumentException("types.isEmpty()");
    }
    int i = 0;
    for (; i < size; i++) {
      if (!legalBeanType(types.get(i))) {
        break;
      }
    }
    if (i == size) {
      types = List.copyOf(types);
    } else {
      final ArrayList newTypes = new ArrayList<>(size);
      for (int j = 0; j < i; j++) {
        newTypes.add(types.get(j)); // the type is known to be legal
      }
      ++i; // skip past the illegal type i was pointing to
      for (; i < size; i++) {
        final TypeMirror t = types.get(i);
        if (legalBeanType(t)) {
          newTypes.add(t);
        }
      }
      if (newTypes.isEmpty()) {
        throw new IllegalArgumentException("types contains no legal bean types: " + types);
      }
      newTypes.trimToSize();
      types = Collections.unmodifiableList(newTypes);
    }
    attributes = List.copyOf(attributes);
    Objects.requireNonNull(governingScopeId, "governingScopeId");
  }

  @Override // Constable
  public final Optional> describeConstable() {
    return Constables.describeConstable(this.attributes())
      .flatMap(attributesDesc -> this.governingScopeId().describeConstable()
               .flatMap(governingScopeIdDesc -> Constables.describeConstable(this.types())
                        .map(typesDesc -> DynamicConstantDesc.of(BSM_INVOKE,
                                                                 MethodHandleDesc.ofConstructor(CD_Id,
                                                                                                CD_List,
                                                                                                CD_List,
                                                                                                CD_NamedAttributeMap,
                                                                                                CD_boolean,
                                                                                                CD_int),
                                                                 typesDesc,
                                                                 attributesDesc,
                                                                 governingScopeIdDesc,
                                                                 this.alternate() ? TRUE : FALSE,
                                                                 this.rank()))));
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy