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.
/*******************************************************************************
* Copyright (c) 2018, TechEmpower, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name TechEmpower, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL TECHEMPOWER, INC. BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
package com.techempower.js.legacy;
import java.io.*;
import java.util.*;
import com.techempower.js.*;
/**
* Writes objects in JavaScript notation. The mapping from Java types to
* JavaScript types is as follows, in order of precedence:
*
*
*
null -> null
*
boolean -> boolean
*
byte, short, int, long, float, double -> number
*
String, char -> string
*
Array (Object[], int[][], etc.) -> array
*
custom* -> string, object, or array
*
Map -> object
*
Iterable, Iterator, Enumeration -> array
*
everything else -> string
*
*
*
[*] The rendering of all objects other than null, primitives, strings,
* and arrays may be customized. See
* {@link Builder#addVisitorFactory(Class, VisitorFactory)} and
* {@link Builder#renderAsStrings(Class)}.
*
*
Instances of this class are immutable.
*
* @see Visitors
*/
public class LegacyJavaScriptWriter
implements JavaScriptWriter
{
//
// Public static utilities.
//
/**
* Returns the standard, default JavaScriptWriter with no custom behavior.
*/
public static LegacyJavaScriptWriter standard()
{
return STANDARD;
}
/**
* Returns a builder for a JavaScriptWriter with custom behavior for certain
* classes. See {@link Builder#addVisitorFactory(Class, VisitorFactory)}.
*/
public static Builder custom()
{
return new Builder();
}
/**
* A utility for creating JavaScriptWriter instances with custom visitor
* factories.
*
*
Instances of this class are not thread-safe, but the JavaScriptWriter
* instances returned by {@link #build()} are immutable and thread-safe.
*/
public static class Builder
{
private static final Set> UNCUSTOMIZABLE_TYPES
= Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
boolean.class, byte.class, int.class, short.class,
long.class, float.class, double.class, void.class,
Boolean.class, Byte.class, Integer.class, Short.class,
Long.class, Float.class, Double.class, Void.class,
String.class)));
/**
* Ensures that the rendering of the given type can be customized.
*
* @param type The type whose rendering is to be customized.
* @throws IllegalArgumentException if the rendering of the given type
* cannot be customized.
*/
private static void requireCustomizableType(Class> type)
{
if (type.isArray() || UNCUSTOMIZABLE_TYPES.contains(type))
{
throw new IllegalArgumentException(
"Rendering of type \"" + type + "\" cannot be customized.");
}
}
private final LinkedHashMap, VisitorFactory>> visitorFactories
= new LinkedHashMap<>();
private Builder() {}
/**
* Adds a visitor factory for the given class.
*
* @param type The class to associate with a visitor factory.
* @param visitorFactory The visitor factory to be used for the class.
* @return A reference to this builder.
*/
public Builder addVisitorFactory(Class extends T> type,
VisitorFactory extends T> visitorFactory)
{
requireNonNull(type, "type");
requireNonNull(visitorFactory, "visitorFactory");
requireCustomizableType(type);
this.visitorFactories.put(type, visitorFactory);
return this;
}
/**
* Indicates that instances of the given class should be rendered as strings.
*
*
This method is not useful in most cases. You can probably ignore it.
*
*
It is not necessary to call this method unless you want instances of
* {@code type} to render as strings and (a) a visitor factory has already
* been assigned for some supertype of {@code type}, or (b) {@code type} is a
* map, iterable, iterator, or enumeration.
*
* @param type The class to be treated as strings.
* @return A reference to this builder.
*/
public Builder renderAsStrings(Class> type)
{
requireNonNull(type, "type");
requireCustomizableType(type);
this.visitorFactories.put(type, NullVisitorFactory.INSTANCE);
return this;
}
/**
* Returns a JavaScriptWriter whose custom visitor factories are specified
* by this builder.
*/
public LegacyJavaScriptWriter build()
{
return (this.visitorFactories.isEmpty())
? STANDARD
: new LegacyJavaScriptWriter(this.visitorFactories);
}
}
//
// Private static utilities.
//
/**
* The minimum depth at which the writer will being to look for circular
* references in the objects being written.
*/
private static final int CIRCULAR_REFERENCE_MIN_DEPTH = 10;
/**
* The singleton instance returned by {@link #standard()}.
*/
private static final LegacyJavaScriptWriter STANDARD = new LegacyJavaScriptWriter(
Collections., VisitorFactory>>emptyMap());
/**
* A special VisitorFactory implementation that simply indicates that no
* VisitorFactory should be used for a given class, and so instances of
* that class should be rendered as strings.
*/
private enum NullVisitorFactory implements VisitorFactory