/*
* Copyright 2004-2012 the Seasar Foundation and the Others.
*
* 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.seasar.mayaa.impl.cycle.script.rhino;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Undefined;
import org.seasar.mayaa.cycle.ServiceCycle;
import org.seasar.mayaa.cycle.scope.AttributeScope;
import org.seasar.mayaa.impl.cycle.CycleUtil;
/**
* @author Masataka Kurihara (Gluegent, Inc.)
*/
public class NativeServiceCycle extends NativeJavaObject {
private static final long serialVersionUID = 326309209323166932L;
private ServiceCycle _cycle;
public NativeServiceCycle(Scriptable scope, ServiceCycle cycle) {
super(scope, cycle, Map.class);
if (cycle == null) {
throw new IllegalArgumentException();
}
_cycle = cycle;
}
public boolean has(String name, Scriptable start) {
ServiceCycle cycle = CycleUtil.getServiceCycle();
if (cycle.hasAttributeScope(name)
|| CycleUtil.findStandardAttributeScope(name) != null) {
return true;
}
return super.has(name, start);
}
/**
* Indicates whether or not a named property is defined in an object. Does not traverse the prototype chain.
* The property is specified by a String name as defined for the get method.
* @param name the name of the property
* @param start the object in which the lookup began
* @return true if and only if the named property is found in the object
*/
public boolean hasMember(String name, Scriptable start) {
return super.has(name, start);
}
public Object get(String name, Scriptable start) {
ServiceCycle cycle = CycleUtil.getServiceCycle();
if (cycle.hasAttributeScope(name)) {
return cycle.getAttributeScope(name);
}
AttributeScope scope = CycleUtil.findStandardAttributeScope(name);
if (scope != null) {
return scope.getAttribute(name);
}
Object result = super.get(name, start);
if (start == this && result == Scriptable.NOT_FOUND) {
// 先回りしてチェック
if (Scriptable.NOT_FOUND == ScriptableObject.getProperty(getParentScope(), name)) {
// topLevelScopeからも先回りチェックして判断しないと、"java" や "Packages" が undefined になってしまう。
Context cx = Context.getCurrentContext();
if (ScriptRuntime.hasTopCall(cx)) {
ScriptableObject global = (ScriptableObject)ScriptRuntime.getTopCallScope(cx);
result = ScriptableObject.getProperty(global, name);
}
if (result == Scriptable.NOT_FOUND) {
result = Undefined.instance;
}
}
}
return result;
}
protected void addAttributesTo(AttributeScope scope, Set set) {
for (Iterator it = scope.iterateAttributeNames(); it.hasNext();) {
Object attrName = it.next();
if (set.contains(attrName) == false) {
set.add(attrName);
}
}
}
public Object[] getIds() {
Set set = new HashSet();
for (Iterator it = _cycle.iterateAttributeScope(); it.hasNext();) {
AttributeScope attrs = (AttributeScope) it.next();
String scopeName = attrs.getScopeName();
if (set.contains(scopeName) == false) {
set.add(scopeName);
}
}
addAttributesTo(_cycle.getPageScope(), set);
addAttributesTo(_cycle.getRequestScope(), set);
addAttributesTo(_cycle.getSessionScope(), set);
addAttributesTo(_cycle.getApplicationScope(), set);
Object[] ids = super.getIds();
for (int i = 0; i < ids.length; i++) {
Object name = ids[i];
if (set.contains(name) == false) {
set.add(name);
}
}
return set.toArray(new Object[set.size()]);
}
public String getClassName() {
return "serviceCycle";
}
public void put(String name, Scriptable start, Object value) {
if (prototype == null || super.has(name, null)) {
ServiceCycle cycle = CycleUtil.getServiceCycle();
AttributeScope scope;
if (cycle.hasAttributeScope(name)) {
scope = cycle.getAttributeScope(name);
} else {
scope = CycleUtil.findStandardAttributeScope(name);
}
if (scope != null) {
scope.setAttribute(name, value);
} else {
super.put(name, start, value);
}
} else {
prototype.put(name, prototype, value);
}
}
}