/*** * Copyright (c) 2009 Caelum - www.caelum.com.br/opensource All rights reserved. * * 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 br.com.caelum.vraptor.ioc.guice; import br.com.caelum.vraptor.interceptor.TypeNameExtractor; import com.google.inject.Inject; import com.google.inject.Key; import com.google.inject.Provider; import com.google.inject.Scope; /** * * @author Lucas Cavalcanti * @since 3.3.0 * */ public abstract class AbstractScope implements Scope { enum NullObject { INSTANCE } static interface ScopeHolder { Object getAttribute(String name); void setAttribute(String name, Object value); } private TypeNameExtractor extractor; @Inject public void setExtractor(TypeNameExtractor extractor) { this.extractor = extractor; } abstract ScopeHolder getHolder(); abstract String getScopeName(); public <T> Provider<T> scope(final Key<T> key, final Provider<T> creator) { return new ScopedProvider<T>(key, creator); } private class ScopedProvider<T> implements Provider<T> { private final Key<T> key; private final Provider<T> creator; private String name; private ScopedProvider(Key<T> key, Provider<T> creator) { this.key = key; this.creator = creator; } public T get() { ScopeHolder holder = getHolder(); synchronized (holder) { Object obj = holder.getAttribute(getName()); if (NullObject.INSTANCE == obj) { return null; } T t = (T) obj; if (t == null) { t = creator.get(); holder.setAttribute(getName(), (t != null) ? t : NullObject.INSTANCE); } return t; } } @Override public String toString() { return String.format("%s[%s]", creator, getScopeName()); } private String getName() { if (name == null) { name = extractor.nameFor(key.getTypeLiteral().getType()); } return name; } } }