Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you 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.apache.juneau.cp;
import static org.apache.juneau.collections.JsonMap.*;
import static org.apache.juneau.common.internal.StringUtils.*;
import static org.apache.juneau.internal.CollectionUtils.*;
import static java.util.stream.Collectors.*;
import java.lang.annotation.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.stream.*;
import org.apache.juneau.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.marshaller.*;
import org.apache.juneau.reflect.*;
/**
* Java bean store.
*
*
* A simple storage database for beans keyed by type and name.
* Used to retrieve and instantiate beans using an injection-like API.
* It's similar in concept to the injection framework of Spring but greatly simplified in function and not intended to implement a full-fledged injection framework.
*
*
* Beans can be stored with or without names. Named beans are typically resolved using
* the @Named or @Qualified annotations on constructor or method parameters.
*
*
* Beans are added through the following methods:
*
Bean stores can be nested using {@link Builder#parent(BeanStore)}.
*
Bean stores can be made read-only using {@link Builder#readOnly()}.
*
Bean stores can be made thread-safe using {@link Builder#threadSafe()}.
*
*
*
See Also:
*
*/
public class BeanStore {
//-----------------------------------------------------------------------------------------------------------------
// Static
//-----------------------------------------------------------------------------------------------------------------
/**
* Non-existent bean store.
*/
public static final class Void extends BeanStore {}
/**
* Static read-only reusable instance.
*/
public static final BeanStore INSTANCE = create().readOnly().build();
/**
* Static creator.
*
* @return A new {@link Builder} object.
*/
public static Builder create() {
return new Builder();
}
/**
* Static creator.
*
* @param parent Parent bean store. Can be null if this is the root resource.
* @return A new {@link BeanStore} object.
*/
public static BeanStore of(BeanStore parent) {
return create().parent(parent).build();
}
/**
* Static creator.
*
* @param parent Parent bean store. Can be null if this is the root resource.
* @param outer The outer bean used when instantiating inner classes. Can be null.
* @return A new {@link BeanStore} object.
*/
public static BeanStore of(BeanStore parent, Object outer) {
return create().parent(parent).outer(outer).build();
}
//-----------------------------------------------------------------------------------------------------------------
// Builder
//-----------------------------------------------------------------------------------------------------------------
/**
* Builder class.
*/
@FluentSetters
public static class Builder {
BeanStore parent;
boolean readOnly, threadSafe;
Object outer;
Class extends BeanStore> type;
BeanStore impl;
/**
* Constructor.
*/
protected Builder() {}
/**
* Instantiates this bean store.
*
* @return A new bean store.
*/
public BeanStore build() {
if (impl != null)
return impl;
if (type == null || type == BeanStore.class)
return new BeanStore(this);
ClassInfo c = ClassInfo.of(type);
MethodInfo m = c.getDeclaredMethod(
x -> x.isPublic()
&& x.hasNoParams()
&& x.isStatic()
&& x.hasName("getInstance")
);
if (m != null)
return m.invoke(null);
ConstructorInfo ci = c.getPublicConstructor(x -> x.canAccept(this));
if (ci != null)
return ci.invoke(this);
ci = c.getDeclaredConstructor(x -> x.isProtected() && x.canAccept(this));
if (ci != null)
return ci.accessible().invoke(this);
throw new BasicRuntimeException("Could not find a way to instantiate class {0}", type);
}
//-------------------------------------------------------------------------------------------------------------
// Properties
//-------------------------------------------------------------------------------------------------------------
/**
* Specifies the parent bean store.
*
*
* Bean searches are performed recursively up this parent chain.
*
* @param value The setting value.
* @return This object.
*/
@FluentSetter
public Builder parent(BeanStore value) {
parent = value;
return this;
}
/**
* Specifies that the bean store is read-only.
*
*
* This means methods such as {@link BeanStore#addBean(Class, Object)} cannot be used.
*
* @return This object.
*/
@FluentSetter
public Builder readOnly() {
readOnly = true;
return this;
}
/**
* Specifies that the bean store being created should be thread-safe.
*
* @return This object.
*/
@FluentSetter
public Builder threadSafe() {
threadSafe = true;
return this;
}
/**
* Specifies the outer bean context.
*
*
* The outer context bean to use when calling constructors on inner classes.
*
* @param value The outer bean context. Can be null.
* @return This object.
*/
@FluentSetter
public Builder outer(Object value) {
this.outer = value;
return this;
}
/**
* Overrides the bean to return from the {@link #build()} method.
*
* @param value The bean to return from the {@link #build()} method.
* @return This object.
*/
@FluentSetter
public Builder impl(BeanStore value) {
this.impl = value;
return this;
}
/**
* Overrides the bean store type.
*
*
* The specified type must have one of the following:
*
*
A static getInstance() method.
*
A public constructor that takes in this builder.
*
A protected constructor that takes in this builder.
*
*
* @param value The bean store type.
* @return This object.
*/
@FluentSetter
public Builder type(Class extends BeanStore> value) {
this.type = value;
return this;
}
}
//-----------------------------------------------------------------------------------------------------------------
// Instance
//-----------------------------------------------------------------------------------------------------------------
private final Deque> entries;
private final Map,BeanStoreEntry>> unnamedEntries;
final Optional parent;
final Optional