alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ElementSource.java)

This example Java source code file (ElementSource.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

elementsource, inmemorystacktraceelement, integer, list, modulesource, nullable, object, override, stacktraceelement, string, util

The ElementSource.java Java example source code

/**
 * Copyright (C) 2013 Google Inc.
 *
 * 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 com.google.inject.spi;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.inject.internal.util.StackTraceElements;
import com.google.inject.internal.util.StackTraceElements.InMemoryStackTraceElement;

import java.util.List;

/**
 * Contains information about where and how an {@link Element element} was
 * bound.
 * <p>
 * The {@link #getDeclaringSource() declaring source} refers to a location in
 * source code that defines the Guice {@link Element element}. For example, if
 * the element is created from a method annotated by {@literal @Provides}, the
 * declaring source of element would be the method itself.
 * <p>
 * The {@link #getStackTrace()} refers to the sequence of calls ends at one of
 * {@link com.google.inject.Binder} {@code bindXXX()} methods and eventually
 * defines the element. Note that {@link #getStackTrace()} lists
 * {@link StackTraceElement StackTraceElements} in reverse chronological order.
 * The first element (index zero) is the last method call and the last element
 * is the first method invocation. By default, the stack trace is not collected.
 * The default behavior can be changed by setting the
 * {@code guice_include_stack_traces} flag value. The value can be either
 * {@code OFF}, {@code ONLY_FOR_DECLARING_SOURCE} or {@code COMPLETE}. Note that
 * collecting stack traces for every binding can cause a performance hit when
 * the injector is created.
 * <p>
 * The sequence of class names of {@link com.google.inject.Module modules}
 * involved in the element creation can be retrieved by
 * {@link #getModuleClassNames()}. Similar to {@link #getStackTrace()}, the
 * order is reverse chronological. The first module (index 0) is the module that
 * installs the {@link Element element}. The last module is the root module.
 * <p>
 * In order to support the cases where a Guice {@link Element element} is
 * created from another Guice {@link Element element} (original) (e.g., by
 * {@link Element#applyTo}), it also provides a reference to the original
 * element source ({@link #getOriginalElementSource()}).
 *
 * @since 4.0
 */
public final class ElementSource {

  /** 
   * The {@link ElementSource source} of element that this element created from (if there is any),
   * otherwise {@code null}.
   */
  final ElementSource originalElementSource;
  
  /** The {@link ModuleSource source} of module creates the element. */
  final ModuleSource moduleSource;
  
  /** 
   * The partial call stack that starts at the last module {@link Module#Configure(Binder)
   * configure(Binder)} call. The value is empty if stack trace collection is off.
   */
  final InMemoryStackTraceElement[] partialCallStack;
  
  /** 
   * Refers to a single location in source code that causes the element creation. It can be any 
   * object such as {@link Constructor}, {@link Method}, {@link Field}, {@link StackTraceElement}, 
   * etc. For example, if the element is created from a method annotated by {@literal @Provides}, 
   * the declaring source of element would be the method itself.
   */
  final Object declaringSource;

  /**
   * Creates a new {@ElementSource} from the given parameters. 
   * @param originalElementSource The source of element that this element created from (if there is
   * any), otherwise {@code null}.
   * @param declaringSource the source (in)directly declared the element.
   * @param moduleSource the moduleSource when the element is bound
   * @param partialCallStack the partial call stack from the top module to where the element is 
   * bound
   */
  ElementSource(/* @Nullable */ ElementSource originalSource, Object declaringSource, 
      ModuleSource moduleSource, StackTraceElement[] partialCallStack) {
    Preconditions.checkNotNull(declaringSource, "declaringSource cannot be null.");
    Preconditions.checkNotNull(moduleSource, "moduleSource cannot be null.");
    Preconditions.checkNotNull(partialCallStack, "partialCallStack cannot be null.");
    this.originalElementSource = originalSource;
    this.declaringSource = declaringSource;
    this.moduleSource = moduleSource;
    this.partialCallStack = StackTraceElements.convertToInMemoryStackTraceElement(partialCallStack);
  }
  
  /**
   * Returns the {@link ElementSource} of the element this was created or copied from. If this was
   * not created or copied from another element, returns {@code null}.
   */
  public ElementSource getOriginalElementSource() {
    return originalElementSource;
  }
  
  /**
   * Returns a single location in source code that defines the element. It can be any object
   * such as {@link java.lang.reflect.Constructor}, {@link java.lang.reflect.Method},
   * {@link java.lang.reflect.Field}, {@link StackTraceElement}, etc. For
   * example, if the element is created from a method annotated by {@literal @Provides}, the
   * declaring source of element would be the method itself.
   */
  public Object getDeclaringSource() {
    return declaringSource;
  }
  
  /**
   * Returns the class names of modules involved in creating this {@link Element}. The first
   * element (index 0) is the class name of module that defined the element, and the last element
   * is the class name of root module.
   */
  public List<String> getModuleClassNames() {
    return moduleSource.getModuleClassNames();
  }

  /**
   * Returns the position of {@link com.google.inject.Module#configure configure(Binder)} method
   * call in the {@link #getStackTrace stack trace} for modules that their classes returned by
   * {@link #getModuleClassNames}. For example, if the stack trace looks like the following:
   * <p>
   * {@code
   *  0 - Binder.bind(),
   *  1 - ModuleTwo.configure(),
   *  2 - Binder.install(),
   *  3 - ModuleOne.configure(),
   *  4 - theRest(). 
   * }
   * <p>
   * 1 and 3 are returned.
   * <p>
   * In the cases where stack trace is not available (i.e., the stack trace was not collected),
   * it returns -1 for all module positions.
   */
  public List<Integer> getModuleConfigurePositionsInStackTrace() {
    int size = moduleSource.size();
    Integer[] positions = new Integer[size];
    int chunkSize = partialCallStack.length;
    positions[0] = chunkSize - 1;
    ModuleSource current = moduleSource;
    for (int cursor = 1; cursor < size; cursor++) {
      chunkSize = current.getPartialCallStackSize();
      positions[cursor] = positions[cursor - 1] + chunkSize;
      current = current.getParent();
    }
    return ImmutableList.<Integer>copyOf(positions);
  }

  /**
   * Returns the sequence of method calls that ends at one of {@link com.google.inject.Binder}
   * {@code bindXXX()} methods and eventually defines the element. Note that
   * {@link #getStackTrace} lists {@link StackTraceElement StackTraceElements} in reverse
   * chronological order. The first element (index zero) is the last method call and the last
   * element is the first method invocation. In the cases where stack trace is not available
   * (i.e.,the stack trace was not collected), it returns an empty array.
   */
  public StackTraceElement[] getStackTrace() {
    int modulesCallStackSize = moduleSource.getStackTraceSize();
    int chunkSize = partialCallStack.length;
    int size = moduleSource.getStackTraceSize() + chunkSize;
    StackTraceElement[] callStack = new StackTraceElement[size];
    System.arraycopy(
        StackTraceElements.convertToStackTraceElement(partialCallStack), 0, callStack, 0, 
        chunkSize);
    System.arraycopy(moduleSource.getStackTrace(), 0, callStack, chunkSize, modulesCallStackSize);
    return callStack;
  }

  /**
   * Returns {@code getDeclaringSource().toString()} value.
   */
  @Override
  public String toString() {
    return getDeclaringSource().toString();
  }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java ElementSource.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.