package org.jolokia.converter.json;
import java.util.*;
import org.jolokia.converter.json.ValueFaultHandler;
/*
* Copyright 2009-2011 Roland Huss
*
* 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.
*/
/**
* Context class for holding and counting limits. It can also take care
* about cycles, i.e. the context knows when an object is visited the second time.
*
* @author roland
*/
class ObjectSerializationContext {
// =============================================================================
// Context used for detecting call loops and the like
private static final Set<Class> SIMPLE_TYPES = new HashSet<Class>(Arrays.asList(
String.class,
Number.class,
Long.class,
Integer.class,
Boolean.class,
Date.class
));
private Set objectsInCallStack = new HashSet();
private Stack callStack = new Stack();
private final JsonConvertOptions options;
private int objectCount = 0;
/**
* Constructor for the stack context providing processing options
*
* @param pOpts options used for parsing
*/
ObjectSerializationContext(JsonConvertOptions pOpts) {
options = pOpts;
}
/**
* Check, whether a given object has been already seen
*
* @param object to check
* @return true if the object has been already visited
*/
boolean alreadyVisited(Object object) {
return objectsInCallStack.contains(object);
}
/**
* Check whether the max depth of the call stack is exceeded
*
* @return true if the max depth limit has been reached
*/
public boolean maxDepthReached() {
return options.maxDepthReached(objectsInCallStack.size());
}
/**
* Check whether the number of extracted objects exceeds the number of maximum objects to extract
*
* @return true if the number of extracted objects exceeds the maximum number of objects
*/
public boolean maxObjectsExceeded() {
return options.maxObjectExceeded(objectCount);
}
/**
* Get the size of a collection trimmed to the maximum size of collections as configured
*
* @param pCollectionSize the original collection size
* @return the original collection size if smalled than the maximum collection size,
* otherwise the maximum collection size
*/
public int getCollectionSizeTruncated(int pCollectionSize) {
return options.getCollectionSizeTruncated(pCollectionSize);
}
/**
* The fault handler used for errors during serialization
*
* @return the value fault handler
*/
public ValueFaultHandler getValueFaultHandler() {
return options.getValueFaultHandler();
}
// =====================================================
// Tracking methods
/**
* Push a new object on the stack
*
* @param object to push
*/
void push(Object object) {
callStack.push(object);
if (object != null && !SIMPLE_TYPES.contains(object.getClass())) {
objectsInCallStack.add(object);
}
objectCount++;
}
/**
* Remove an object from top of the call stack
* @return the object popped
*/
Object pop() {
Object ret = callStack.pop();
if (ret != null && !SIMPLE_TYPES.contains(ret.getClass())) {
objectsInCallStack.remove(ret);
}
return ret;
}
}