mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
Move test fixtures to samples/
This commit is contained in:
243
samples/java/HtmlDomParserContext.java
Normal file
243
samples/java/HtmlDomParserContext.java
Normal file
@@ -0,0 +1,243 @@
|
||||
/**
|
||||
* (The MIT License)
|
||||
*
|
||||
* Copyright (c) 2008 - 2012:
|
||||
*
|
||||
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
||||
* * {Mike Dalessio}[http://mike.daless.io]
|
||||
* * {Charles Nutter}[http://blog.headius.com]
|
||||
* * {Sergio Arbeo}[http://www.serabe.com]
|
||||
* * {Patrick Mahoney}[http://polycrystal.org]
|
||||
* * {Yoko Harada}[http://yokolet.blogspot.com]
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nokogiri.internals;
|
||||
|
||||
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
|
||||
import static nokogiri.internals.NokogiriHelpers.isNamespace;
|
||||
import static nokogiri.internals.NokogiriHelpers.stringOrNil;
|
||||
import nokogiri.HtmlDocument;
|
||||
import nokogiri.NokogiriService;
|
||||
import nokogiri.XmlDocument;
|
||||
|
||||
import org.apache.xerces.parsers.DOMParser;
|
||||
import org.apache.xerces.xni.Augmentations;
|
||||
import org.apache.xerces.xni.QName;
|
||||
import org.apache.xerces.xni.XMLAttributes;
|
||||
import org.apache.xerces.xni.XNIException;
|
||||
import org.apache.xerces.xni.parser.XMLDocumentFilter;
|
||||
import org.apache.xerces.xni.parser.XMLParserConfiguration;
|
||||
import org.cyberneko.html.HTMLConfiguration;
|
||||
import org.cyberneko.html.filters.DefaultFilter;
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyClass;
|
||||
import org.jruby.runtime.ThreadContext;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* Parser for HtmlDocument. This class actually parses HtmlDocument using NekoHtml.
|
||||
*
|
||||
* @author sergio
|
||||
* @author Patrick Mahoney <pat@polycrystal.org>
|
||||
* @author Yoko Harada <yokolet@gmail.com>
|
||||
*/
|
||||
public class HtmlDomParserContext extends XmlDomParserContext {
|
||||
|
||||
public HtmlDomParserContext(Ruby runtime, IRubyObject options) {
|
||||
super(runtime, options);
|
||||
}
|
||||
|
||||
public HtmlDomParserContext(Ruby runtime, IRubyObject encoding, IRubyObject options) {
|
||||
super(runtime, encoding, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initErrorHandler() {
|
||||
if (options.strict) {
|
||||
errorHandler = new NokogiriStrictErrorHandler(options.noError, options.noWarning);
|
||||
} else {
|
||||
errorHandler = new NokogiriNonStrictErrorHandler4NekoHtml(options.noError, options.noWarning);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initParser(Ruby runtime) {
|
||||
XMLParserConfiguration config = new HTMLConfiguration();
|
||||
XMLDocumentFilter removeNSAttrsFilter = new RemoveNSAttrsFilter();
|
||||
XMLDocumentFilter elementValidityCheckFilter = new ElementValidityCheckFilter(errorHandler);
|
||||
//XMLDocumentFilter[] filters = { removeNSAttrsFilter, elementValidityCheckFilter};
|
||||
XMLDocumentFilter[] filters = { elementValidityCheckFilter};
|
||||
|
||||
config.setErrorHandler(this.errorHandler);
|
||||
parser = new DOMParser(config);
|
||||
|
||||
// see http://nekohtml.sourceforge.net/settings.html for details
|
||||
setProperty("http://cyberneko.org/html/properties/default-encoding", java_encoding);
|
||||
setProperty("http://cyberneko.org/html/properties/names/elems", "lower");
|
||||
setProperty("http://cyberneko.org/html/properties/names/attrs", "lower");
|
||||
setProperty("http://cyberneko.org/html/properties/filters", filters);
|
||||
setFeature("http://cyberneko.org/html/features/report-errors", true);
|
||||
setFeature("http://xml.org/sax/features/namespaces", false);
|
||||
setFeature("http://cyberneko.org/html/features/insert-doctype", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable NekoHTML feature for balancing tags in a document fragment.
|
||||
*
|
||||
* This method is used in XmlNode#in_context method.
|
||||
*/
|
||||
public void enableDocumentFragment() {
|
||||
setFeature("http://cyberneko.org/html/features/balance-tags/document-fragment", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XmlDocument getNewEmptyDocument(ThreadContext context) {
|
||||
IRubyObject[] args = new IRubyObject[0];
|
||||
return (XmlDocument) XmlDocument.rbNew(context, getNokogiriClass(context.getRuntime(), "Nokogiri::HTML::Document"), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XmlDocument wrapDocument(ThreadContext context,
|
||||
RubyClass klazz,
|
||||
Document document) {
|
||||
HtmlDocument htmlDocument = (HtmlDocument) NokogiriService.HTML_DOCUMENT_ALLOCATOR.allocate(context.getRuntime(), klazz);
|
||||
htmlDocument.setDocumentNode(context, document);
|
||||
if (ruby_encoding.isNil()) {
|
||||
// ruby_encoding might have detected by HtmlDocument::EncodingReader
|
||||
if (detected_encoding != null && !detected_encoding.isNil()) {
|
||||
ruby_encoding = detected_encoding;
|
||||
} else {
|
||||
// no encoding given & no encoding detected, then try to get it
|
||||
String charset = tryGetCharsetFromHtml5MetaTag(document);
|
||||
ruby_encoding = stringOrNil(context.getRuntime(), charset);
|
||||
}
|
||||
}
|
||||
htmlDocument.setEncoding(ruby_encoding);
|
||||
htmlDocument.setParsedEncoding(java_encoding);
|
||||
return htmlDocument;
|
||||
}
|
||||
|
||||
// NekoHtml doesn't understand HTML5 meta tag format. This fails to detect charset
|
||||
// from an HTML5 style meta tag. Luckily, the meta tag and charset exists in DOM tree
|
||||
// so, this method attempts to find the charset.
|
||||
private String tryGetCharsetFromHtml5MetaTag(Document document) {
|
||||
if (!"html".equalsIgnoreCase(document.getDocumentElement().getNodeName())) return null;
|
||||
NodeList list = document.getDocumentElement().getChildNodes();
|
||||
for (int i = 0; i < list.getLength(); i++) {
|
||||
if ("head".equalsIgnoreCase(list.item(i).getNodeName())) {
|
||||
NodeList headers = list.item(i).getChildNodes();
|
||||
for (int j = 0; j < headers.getLength(); j++) {
|
||||
if ("meta".equalsIgnoreCase(headers.item(j).getNodeName())) {
|
||||
NamedNodeMap nodeMap = headers.item(j).getAttributes();
|
||||
for (int k = 0; k < nodeMap.getLength(); k++) {
|
||||
if ("charset".equalsIgnoreCase(nodeMap.item(k).getNodeName())) {
|
||||
return nodeMap.item(k).getNodeValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter to strip out attributes that pertain to XML namespaces.
|
||||
*/
|
||||
public static class RemoveNSAttrsFilter extends DefaultFilter {
|
||||
@Override
|
||||
public void startElement(QName element, XMLAttributes attrs,
|
||||
Augmentations augs) throws XNIException {
|
||||
int i;
|
||||
for (i = 0; i < attrs.getLength(); ++i) {
|
||||
if (isNamespace(attrs.getQName(i))) {
|
||||
attrs.removeAttributeAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
element.uri = null;
|
||||
super.startElement(element, attrs, augs);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ElementValidityCheckFilter extends DefaultFilter {
|
||||
private NokogiriErrorHandler errorHandler;
|
||||
|
||||
private ElementValidityCheckFilter(NokogiriErrorHandler errorHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
// element names from xhtml1-strict.dtd
|
||||
private static String[][] element_names = {
|
||||
{"a", "abbr", "acronym", "address", "area"},
|
||||
{"b", "base", "basefont", "bdo", "big", "blockquote", "body", "br", "button"},
|
||||
{"caption", "cite", "code", "col", "colgroup"},
|
||||
{"dd", "del", "dfn", "div", "dl", "dt"},
|
||||
{"em"},
|
||||
{"fieldset", "font", "form", "frame", "frameset"},
|
||||
{}, // g
|
||||
{"h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "html"},
|
||||
{"i", "iframe", "img", "input", "ins"},
|
||||
{}, // j
|
||||
{"kbd"},
|
||||
{"label", "legend", "li", "link"},
|
||||
{"map", "meta"},
|
||||
{"noframes", "noscript"},
|
||||
{"object", "ol", "optgroup", "option"},
|
||||
{"p", "param", "pre"},
|
||||
{"q"},
|
||||
{}, // r
|
||||
{"s", "samp", "script", "select", "small", "span", "strike", "strong", "style", "sub", "sup"},
|
||||
{"table", "tbody", "td", "textarea", "tfoot", "th", "thead", "title", "tr", "tt"},
|
||||
{"u", "ul"},
|
||||
{"var"},
|
||||
{}, // w
|
||||
{}, // x
|
||||
{}, // y
|
||||
{} // z
|
||||
};
|
||||
|
||||
private boolean isValid(String testee) {
|
||||
char[] c = testee.toCharArray();
|
||||
int index = new Integer(c[0]) - 97;
|
||||
if (index > 25) return false;
|
||||
for (int i=0; i<element_names[index].length; i++) {
|
||||
if (testee.equals(element_names[index][i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(QName name, XMLAttributes attrs, Augmentations augs) throws XNIException {
|
||||
if (!isValid(name.rawname)) {
|
||||
errorHandler.getErrors().add(new Exception("Tag " + name.rawname + " invalid"));
|
||||
}
|
||||
super.startElement(name, attrs, augs);
|
||||
}
|
||||
}
|
||||
}
|
||||
322
samples/java/Hudson.java
Normal file
322
samples/java/Hudson.java
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
|
||||
* Erik Ramfelt, Koichi Fujikawa, Red Hat, Inc., Seiji Sogabe,
|
||||
* Stephen Connolly, Tom Huybrechts, Yahoo! Inc., Alan Harder, CloudBees, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package hudson.model;
|
||||
|
||||
import hudson.ExtensionListView;
|
||||
import hudson.Functions;
|
||||
import hudson.Platform;
|
||||
import hudson.PluginManager;
|
||||
import hudson.cli.declarative.CLIResolver;
|
||||
import hudson.model.listeners.ItemListener;
|
||||
import hudson.slaves.ComputerListener;
|
||||
import hudson.util.CopyOnWriteList;
|
||||
import hudson.util.FormValidation;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jvnet.hudson.reactor.ReactorException;
|
||||
import org.kohsuke.stapler.QueryParameter;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.StaplerRequest;
|
||||
import org.kohsuke.stapler.StaplerResponse;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static hudson.Util.fixEmpty;
|
||||
|
||||
public class Hudson extends Jenkins {
|
||||
|
||||
/**
|
||||
* List of registered {@link hudson.model.listeners.ItemListener}s.
|
||||
* @deprecated as of 1.286
|
||||
*/
|
||||
private transient final CopyOnWriteList<ItemListener> itemListeners = ExtensionListView.createCopyOnWriteList(ItemListener.class);
|
||||
|
||||
/**
|
||||
* List of registered {@link hudson.slaves.ComputerListener}s.
|
||||
* @deprecated as of 1.286
|
||||
*/
|
||||
private transient final CopyOnWriteList<ComputerListener> computerListeners = ExtensionListView.createCopyOnWriteList(ComputerListener.class);
|
||||
|
||||
|
||||
@CLIResolver
|
||||
public static Hudson getInstance() {
|
||||
return (Hudson)Jenkins.getInstance();
|
||||
}
|
||||
|
||||
public Hudson(File root, ServletContext context) throws IOException, InterruptedException, ReactorException {
|
||||
this(root,context,null);
|
||||
}
|
||||
|
||||
public Hudson(File root, ServletContext context, PluginManager pluginManager) throws IOException, InterruptedException, ReactorException {
|
||||
super(root, context, pluginManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the installed {@link ItemListener}s.
|
||||
*
|
||||
* @deprecated as of 1.286.
|
||||
* Use {@link ItemListener#all()}.
|
||||
*/
|
||||
public CopyOnWriteList<ItemListener> getJobListeners() {
|
||||
return itemListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the installed {@link ComputerListener}s.
|
||||
*
|
||||
* @deprecated as of 1.286.
|
||||
* Use {@link ComputerListener#all()}.
|
||||
*/
|
||||
public CopyOnWriteList<ComputerListener> getComputerListeners() {
|
||||
return computerListeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the slave node of the give name, hooked under this Hudson.
|
||||
*
|
||||
* @deprecated
|
||||
* Use {@link #getNode(String)}. Since 1.252.
|
||||
*/
|
||||
public Slave getSlave(String name) {
|
||||
Node n = getNode(name);
|
||||
if (n instanceof Slave)
|
||||
return (Slave)n;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #getNodes()}. Since 1.252.
|
||||
*/
|
||||
public List<Slave> getSlaves() {
|
||||
return (List)slaves;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the slave list.
|
||||
*
|
||||
* @deprecated
|
||||
* Use {@link #setNodes(List)}. Since 1.252.
|
||||
*/
|
||||
public void setSlaves(List<Slave> slaves) throws IOException {
|
||||
setNodes(slaves);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Left only for the compatibility of URLs.
|
||||
* Should not be invoked for any other purpose.
|
||||
*/
|
||||
public TopLevelItem getJob(String name) {
|
||||
return getItem(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Used only for mapping jobs to URL in a case-insensitive fashion.
|
||||
*/
|
||||
public TopLevelItem getJobCaseInsensitive(String name) {
|
||||
String match = Functions.toEmailSafeString(name);
|
||||
for(TopLevelItem item : getItems()) {
|
||||
if(Functions.toEmailSafeString(item.getName()).equalsIgnoreCase(match)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 1.317
|
||||
* Use {@link #doQuietDown()} instead.
|
||||
*/
|
||||
public synchronized void doQuietDown(StaplerResponse rsp) throws IOException, ServletException {
|
||||
doQuietDown().generateResponse(null, rsp, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* RSS feed for log entries.
|
||||
*
|
||||
* @deprecated
|
||||
* As on 1.267, moved to "/log/rss..."
|
||||
*/
|
||||
public void doLogRss( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
|
||||
String qs = req.getQueryString();
|
||||
rsp.sendRedirect2("./log/rss"+(qs==null?"":'?'+qs));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated as of 1.294
|
||||
* Define your own check method, instead of relying on this generic one.
|
||||
*/
|
||||
public void doFieldCheck(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
|
||||
doFieldCheck(
|
||||
fixEmpty(req.getParameter("value")),
|
||||
fixEmpty(req.getParameter("type")),
|
||||
fixEmpty(req.getParameter("errorText")),
|
||||
fixEmpty(req.getParameter("warningText"))).generateResponse(req,rsp,this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value for a field is set; if not an error or warning text is displayed.
|
||||
* If the parameter "value" is not set then the parameter "errorText" is displayed
|
||||
* as an error text. If the parameter "errorText" is not set, then the parameter "warningText"
|
||||
* is displayed as a warning text.
|
||||
* <p>
|
||||
* If the text is set and the parameter "type" is set, it will validate that the value is of the
|
||||
* correct type. Supported types are "number, "number-positive" and "number-negative".
|
||||
*
|
||||
* @deprecated as of 1.324
|
||||
* Either use client-side validation (e.g. class="required number")
|
||||
* or define your own check method, instead of relying on this generic one.
|
||||
*/
|
||||
public FormValidation doFieldCheck(@QueryParameter(fixEmpty=true) String value,
|
||||
@QueryParameter(fixEmpty=true) String type,
|
||||
@QueryParameter(fixEmpty=true) String errorText,
|
||||
@QueryParameter(fixEmpty=true) String warningText) {
|
||||
if (value == null) {
|
||||
if (errorText != null)
|
||||
return FormValidation.error(errorText);
|
||||
if (warningText != null)
|
||||
return FormValidation.warning(warningText);
|
||||
return FormValidation.error("No error or warning text was set for fieldCheck().");
|
||||
}
|
||||
|
||||
if (type != null) {
|
||||
try {
|
||||
if (type.equalsIgnoreCase("number")) {
|
||||
NumberFormat.getInstance().parse(value);
|
||||
} else if (type.equalsIgnoreCase("number-positive")) {
|
||||
if (NumberFormat.getInstance().parse(value).floatValue() <= 0)
|
||||
return FormValidation.error(Messages.Hudson_NotAPositiveNumber());
|
||||
} else if (type.equalsIgnoreCase("number-negative")) {
|
||||
if (NumberFormat.getInstance().parse(value).floatValue() >= 0)
|
||||
return FormValidation.error(Messages.Hudson_NotANegativeNumber());
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
return FormValidation.error(Messages.Hudson_NotANumber());
|
||||
}
|
||||
}
|
||||
|
||||
return FormValidation.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link Functions#isWindows()}.
|
||||
*/
|
||||
public static boolean isWindows() {
|
||||
return File.pathSeparatorChar==';';
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link hudson.Platform#isDarwin()}
|
||||
*/
|
||||
public static boolean isDarwin() {
|
||||
return Platform.isDarwin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2007-12-18.
|
||||
* Use {@link #checkPermission(hudson.security.Permission)}
|
||||
*/
|
||||
public static boolean adminCheck() throws IOException {
|
||||
return adminCheck(Stapler.getCurrentRequest(), Stapler.getCurrentResponse());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2007-12-18.
|
||||
* Use {@link #checkPermission(hudson.security.Permission)}
|
||||
*/
|
||||
public static boolean adminCheck(StaplerRequest req,StaplerResponse rsp) throws IOException {
|
||||
if (isAdmin(req)) return true;
|
||||
|
||||
rsp.sendError(StaplerResponse.SC_FORBIDDEN);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current user (for which we are processing the current request)
|
||||
* has the admin access.
|
||||
*
|
||||
* @deprecated since 2007-12-18.
|
||||
* This method is deprecated when Hudson moved from simple Unix root-like model
|
||||
* of "admin gets to do everything, and others don't have any privilege" to more
|
||||
* complex {@link hudson.security.ACL} and {@link hudson.security.Permission} based scheme.
|
||||
*
|
||||
* <p>
|
||||
* For a quick migration, use {@code Hudson.getInstance().getACL().hasPermission(Hudson.ADMINISTER)}
|
||||
* To check if the user has the 'administer' role in Hudson.
|
||||
*
|
||||
* <p>
|
||||
* But ideally, your plugin should first identify a suitable {@link hudson.security.Permission} (or create one,
|
||||
* if appropriate), then identify a suitable {@link hudson.security.AccessControlled} object to check its permission
|
||||
* against.
|
||||
*/
|
||||
public static boolean isAdmin() {
|
||||
return Jenkins.getInstance().getACL().hasPermission(ADMINISTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2007-12-18.
|
||||
* Define a custom {@link hudson.security.Permission} and check against ACL.
|
||||
* See {@link #isAdmin()} for more instructions.
|
||||
*/
|
||||
public static boolean isAdmin(StaplerRequest req) {
|
||||
return isAdmin();
|
||||
}
|
||||
|
||||
static {
|
||||
XSTREAM.alias("hudson",Hudson.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated only here for backward comp
|
||||
*/
|
||||
public static final class MasterComputer extends Jenkins.MasterComputer {
|
||||
// no op
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated only here for backward comp
|
||||
*/
|
||||
public static class CloudList extends Jenkins.CloudList {
|
||||
public CloudList(Jenkins h) {
|
||||
super(h);
|
||||
}
|
||||
|
||||
public CloudList() {// needed for XStream deserialization
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
598
samples/java/NokogiriService.java
Normal file
598
samples/java/NokogiriService.java
Normal file
@@ -0,0 +1,598 @@
|
||||
/**
|
||||
* (The MIT License)
|
||||
*
|
||||
* Copyright (c) 2008 - 2011:
|
||||
*
|
||||
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
||||
* * {Mike Dalessio}[http://mike.daless.io]
|
||||
* * {Charles Nutter}[http://blog.headius.com]
|
||||
* * {Sergio Arbeo}[http://www.serabe.com]
|
||||
* * {Patrick Mahoney}[http://polycrystal.org]
|
||||
* * {Yoko Harada}[http://yokolet.blogspot.com]
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* 'Software'), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nokogiri;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyArray;
|
||||
import org.jruby.RubyClass;
|
||||
import org.jruby.RubyFixnum;
|
||||
import org.jruby.RubyModule;
|
||||
import org.jruby.runtime.ObjectAllocator;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.jruby.runtime.load.BasicLibraryService;
|
||||
|
||||
/**
|
||||
* Class to provide Nokogiri. This class is used to make "require 'nokogiri'" work
|
||||
* in JRuby. Also, this class holds a Ruby type cache and allocators of Ruby types.
|
||||
*
|
||||
* @author headius
|
||||
* @author Yoko Harada <yokolet@gmail.com>
|
||||
*/
|
||||
public class NokogiriService implements BasicLibraryService {
|
||||
public static final String nokogiriClassCacheGvarName = "$NOKOGIRI_CLASS_CACHE";
|
||||
public static Map<String, RubyClass> nokogiriClassCache;
|
||||
|
||||
public boolean basicLoad(Ruby ruby) {
|
||||
init(ruby);
|
||||
createNokogiriClassCahce(ruby);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void createNokogiriClassCahce(Ruby ruby) {
|
||||
nokogiriClassCache = Collections.synchronizedMap(new HashMap<String, RubyClass>());
|
||||
nokogiriClassCache.put("Nokogiri::EncodingHandler", (RubyClass)ruby.getClassFromPath("Nokogiri::EncodingHandler"));
|
||||
nokogiriClassCache.put("Nokogiri::HTML::Document", (RubyClass)ruby.getClassFromPath("Nokogiri::HTML::Document"));
|
||||
nokogiriClassCache.put("Nokogiri::HTML::ElementDescription", (RubyClass)ruby.getClassFromPath("Nokogiri::HTML::ElementDescription"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Attr", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Attr"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Document", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Document"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::DocumentFragment", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::DocumentFragment"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::DTD", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::DTD"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Text", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Text"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Comment", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Comment"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Element", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Element"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::ElementContent", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ElementContent"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::ElementDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ElementDecl"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::EntityDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::EntityDecl"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::EntityReference", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::EntityReference"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::ProcessingInstruction", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::ProcessingInstruction"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::CDATA", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::CDATA"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Node", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Node"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::NodeSet", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::NodeSet"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Namespace", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Namespace"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::SyntaxError", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SyntaxError"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Reader", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Reader"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::RelaxNG", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::RelaxNG"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::Schema", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::Schema"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::XPathContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::XPathContext"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::AttributeDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::AttributeDecl"));
|
||||
nokogiriClassCache.put("Nokogiri::XML::SAX::ParserContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SAX::ParserContext"));
|
||||
}
|
||||
|
||||
private void init(Ruby ruby) {
|
||||
RubyModule nokogiri = ruby.defineModule("Nokogiri");
|
||||
RubyModule xmlModule = nokogiri.defineModuleUnder("XML");
|
||||
RubyModule xmlSaxModule = xmlModule.defineModuleUnder("SAX");
|
||||
RubyModule htmlModule = nokogiri.defineModuleUnder("HTML");
|
||||
RubyModule htmlSaxModule = htmlModule.defineModuleUnder("SAX");
|
||||
RubyModule xsltModule = nokogiri.defineModuleUnder("XSLT");
|
||||
|
||||
createNokogiriModule(ruby, nokogiri);
|
||||
createSyntaxErrors(ruby, nokogiri, xmlModule);
|
||||
RubyClass xmlNode = createXmlModule(ruby, xmlModule);
|
||||
createHtmlModule(ruby, htmlModule);
|
||||
createDocuments(ruby, xmlModule, htmlModule, xmlNode);
|
||||
createSaxModule(ruby, xmlSaxModule, htmlSaxModule);
|
||||
createXsltModule(ruby, xsltModule);
|
||||
}
|
||||
|
||||
private void createNokogiriModule(Ruby ruby, RubyModule nokogiri) {;
|
||||
RubyClass encHandler = nokogiri.defineClassUnder("EncodingHandler", ruby.getObject(), ENCODING_HANDLER_ALLOCATOR);
|
||||
encHandler.defineAnnotatedMethods(EncodingHandler.class);
|
||||
}
|
||||
|
||||
private void createSyntaxErrors(Ruby ruby, RubyModule nokogiri, RubyModule xmlModule) {
|
||||
RubyClass syntaxError = nokogiri.defineClassUnder("SyntaxError", ruby.getStandardError(), ruby.getStandardError().getAllocator());
|
||||
RubyClass xmlSyntaxError = xmlModule.defineClassUnder("SyntaxError", syntaxError, XML_SYNTAXERROR_ALLOCATOR);
|
||||
xmlSyntaxError.defineAnnotatedMethods(XmlSyntaxError.class);
|
||||
}
|
||||
|
||||
private RubyClass createXmlModule(Ruby ruby, RubyModule xmlModule) {
|
||||
RubyClass node = xmlModule.defineClassUnder("Node", ruby.getObject(), XML_NODE_ALLOCATOR);
|
||||
node.defineAnnotatedMethods(XmlNode.class);
|
||||
|
||||
RubyClass attr = xmlModule.defineClassUnder("Attr", node, XML_ATTR_ALLOCATOR);
|
||||
attr.defineAnnotatedMethods(XmlAttr.class);
|
||||
|
||||
RubyClass attrDecl = xmlModule.defineClassUnder("AttributeDecl", node, XML_ATTRIBUTE_DECL_ALLOCATOR);
|
||||
attrDecl.defineAnnotatedMethods(XmlAttributeDecl.class);
|
||||
|
||||
RubyClass characterData = xmlModule.defineClassUnder("CharacterData", node, null);
|
||||
|
||||
RubyClass comment = xmlModule.defineClassUnder("Comment", characterData, XML_COMMENT_ALLOCATOR);
|
||||
comment.defineAnnotatedMethods(XmlComment.class);
|
||||
|
||||
RubyClass text = xmlModule.defineClassUnder("Text", characterData, XML_TEXT_ALLOCATOR);
|
||||
text.defineAnnotatedMethods(XmlText.class);
|
||||
|
||||
RubyModule cdata = xmlModule.defineClassUnder("CDATA", text, XML_CDATA_ALLOCATOR);
|
||||
cdata.defineAnnotatedMethods(XmlCdata.class);
|
||||
|
||||
RubyClass dtd = xmlModule.defineClassUnder("DTD", node, XML_DTD_ALLOCATOR);
|
||||
dtd.defineAnnotatedMethods(XmlDtd.class);
|
||||
|
||||
RubyClass documentFragment = xmlModule.defineClassUnder("DocumentFragment", node, XML_DOCUMENT_FRAGMENT_ALLOCATOR);
|
||||
documentFragment.defineAnnotatedMethods(XmlDocumentFragment.class);
|
||||
|
||||
RubyClass element = xmlModule.defineClassUnder("Element", node, XML_ELEMENT_ALLOCATOR);
|
||||
element.defineAnnotatedMethods(XmlElement.class);
|
||||
|
||||
RubyClass elementContent = xmlModule.defineClassUnder("ElementContent", ruby.getObject(), XML_ELEMENT_CONTENT_ALLOCATOR);
|
||||
elementContent.defineAnnotatedMethods(XmlElementContent.class);
|
||||
|
||||
RubyClass elementDecl = xmlModule.defineClassUnder("ElementDecl", node, XML_ELEMENT_DECL_ALLOCATOR);
|
||||
elementDecl.defineAnnotatedMethods(XmlElementDecl.class);
|
||||
|
||||
RubyClass entityDecl = xmlModule.defineClassUnder("EntityDecl", node, XML_ENTITY_DECL_ALLOCATOR);
|
||||
entityDecl.defineAnnotatedMethods(XmlEntityDecl.class);
|
||||
|
||||
entityDecl.defineConstant("INTERNAL_GENERAL", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_GENERAL));
|
||||
entityDecl.defineConstant("EXTERNAL_GENERAL_PARSED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_GENERAL_PARSED));
|
||||
entityDecl.defineConstant("EXTERNAL_GENERAL_UNPARSED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_GENERAL_UNPARSED));
|
||||
entityDecl.defineConstant("INTERNAL_PARAMETER", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_PARAMETER));
|
||||
entityDecl.defineConstant("EXTERNAL_PARAMETER", RubyFixnum.newFixnum(ruby, XmlEntityDecl.EXTERNAL_PARAMETER));
|
||||
entityDecl.defineConstant("INTERNAL_PREDEFINED", RubyFixnum.newFixnum(ruby, XmlEntityDecl.INTERNAL_PREDEFINED));
|
||||
|
||||
RubyClass entref = xmlModule.defineClassUnder("EntityReference", node, XML_ENTITY_REFERENCE_ALLOCATOR);
|
||||
entref.defineAnnotatedMethods(XmlEntityReference.class);
|
||||
|
||||
RubyClass namespace = xmlModule.defineClassUnder("Namespace", ruby.getObject(), XML_NAMESPACE_ALLOCATOR);
|
||||
namespace.defineAnnotatedMethods(XmlNamespace.class);
|
||||
|
||||
RubyClass nodeSet = xmlModule.defineClassUnder("NodeSet", ruby.getObject(), XML_NODESET_ALLOCATOR);
|
||||
nodeSet.defineAnnotatedMethods(XmlNodeSet.class);
|
||||
|
||||
RubyClass pi = xmlModule.defineClassUnder("ProcessingInstruction", node, XML_PROCESSING_INSTRUCTION_ALLOCATOR);
|
||||
pi.defineAnnotatedMethods(XmlProcessingInstruction.class);
|
||||
|
||||
RubyClass reader = xmlModule.defineClassUnder("Reader", ruby.getObject(), XML_READER_ALLOCATOR);
|
||||
reader.defineAnnotatedMethods(XmlReader.class);
|
||||
|
||||
RubyClass schema = xmlModule.defineClassUnder("Schema", ruby.getObject(), XML_SCHEMA_ALLOCATOR);
|
||||
schema.defineAnnotatedMethods(XmlSchema.class);
|
||||
|
||||
RubyClass relaxng = xmlModule.defineClassUnder("RelaxNG", schema, XML_RELAXNG_ALLOCATOR);
|
||||
relaxng.defineAnnotatedMethods(XmlRelaxng.class);
|
||||
|
||||
RubyClass xpathContext = xmlModule.defineClassUnder("XPathContext", ruby.getObject(), XML_XPATHCONTEXT_ALLOCATOR);
|
||||
xpathContext.defineAnnotatedMethods(XmlXpathContext.class);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private void createHtmlModule(Ruby ruby, RubyModule htmlModule) {
|
||||
RubyClass htmlElemDesc = htmlModule.defineClassUnder("ElementDescription", ruby.getObject(), HTML_ELEMENT_DESCRIPTION_ALLOCATOR);
|
||||
htmlElemDesc.defineAnnotatedMethods(HtmlElementDescription.class);
|
||||
|
||||
RubyClass htmlEntityLookup = htmlModule.defineClassUnder("EntityLookup", ruby.getObject(), HTML_ENTITY_LOOKUP_ALLOCATOR);
|
||||
htmlEntityLookup.defineAnnotatedMethods(HtmlEntityLookup.class);
|
||||
}
|
||||
|
||||
private void createDocuments(Ruby ruby, RubyModule xmlModule, RubyModule htmlModule, RubyClass node) {
|
||||
RubyClass xmlDocument = xmlModule.defineClassUnder("Document", node, XML_DOCUMENT_ALLOCATOR);
|
||||
xmlDocument.defineAnnotatedMethods(XmlDocument.class);
|
||||
|
||||
//RubyModule htmlDoc = html.defineOrGetClassUnder("Document", document);
|
||||
RubyModule htmlDocument = htmlModule.defineClassUnder("Document", xmlDocument, HTML_DOCUMENT_ALLOCATOR);
|
||||
htmlDocument.defineAnnotatedMethods(HtmlDocument.class);
|
||||
}
|
||||
|
||||
private void createSaxModule(Ruby ruby, RubyModule xmlSaxModule, RubyModule htmlSaxModule) {
|
||||
RubyClass xmlSaxParserContext = xmlSaxModule.defineClassUnder("ParserContext", ruby.getObject(), XML_SAXPARSER_CONTEXT_ALLOCATOR);
|
||||
xmlSaxParserContext.defineAnnotatedMethods(XmlSaxParserContext.class);
|
||||
|
||||
RubyClass xmlSaxPushParser = xmlSaxModule.defineClassUnder("PushParser", ruby.getObject(), XML_SAXPUSHPARSER_ALLOCATOR);
|
||||
xmlSaxPushParser.defineAnnotatedMethods(XmlSaxPushParser.class);
|
||||
|
||||
RubyClass htmlSaxParserContext = htmlSaxModule.defineClassUnder("ParserContext", xmlSaxParserContext, HTML_SAXPARSER_CONTEXT_ALLOCATOR);
|
||||
htmlSaxParserContext.defineAnnotatedMethods(HtmlSaxParserContext.class);
|
||||
}
|
||||
|
||||
private void createXsltModule(Ruby ruby, RubyModule xsltModule) {
|
||||
RubyClass stylesheet = xsltModule.defineClassUnder("Stylesheet", ruby.getObject(), XSLT_STYLESHEET_ALLOCATOR);
|
||||
stylesheet.defineAnnotatedMethods(XsltStylesheet.class);
|
||||
xsltModule.defineAnnotatedMethod(XsltStylesheet.class, "register");
|
||||
}
|
||||
|
||||
private static ObjectAllocator ENCODING_HANDLER_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new EncodingHandler(runtime, klazz, "");
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator HTML_DOCUMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private HtmlDocument htmlDocument = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (htmlDocument == null) htmlDocument = new HtmlDocument(runtime, klazz);
|
||||
try {
|
||||
HtmlDocument clone = (HtmlDocument) htmlDocument.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new HtmlDocument(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator HTML_SAXPARSER_CONTEXT_ALLOCATOR = new ObjectAllocator() {
|
||||
private HtmlSaxParserContext htmlSaxParserContext = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (htmlSaxParserContext == null) htmlSaxParserContext = new HtmlSaxParserContext(runtime, klazz);
|
||||
try {
|
||||
HtmlSaxParserContext clone = (HtmlSaxParserContext) htmlSaxParserContext.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new HtmlSaxParserContext(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator HTML_ELEMENT_DESCRIPTION_ALLOCATOR =
|
||||
new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new HtmlElementDescription(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator HTML_ENTITY_LOOKUP_ALLOCATOR =
|
||||
new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new HtmlEntityLookup(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_ATTR_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlAttr xmlAttr = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlAttr == null) xmlAttr = new XmlAttr(runtime, klazz);
|
||||
try {
|
||||
XmlAttr clone = (XmlAttr) xmlAttr.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlAttr(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_CDATA_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlCdata xmlCdata = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlCdata == null) xmlCdata = new XmlCdata(runtime, klazz);
|
||||
try {
|
||||
XmlCdata clone = (XmlCdata) xmlCdata.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlCdata(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_COMMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlComment xmlComment = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlComment == null) xmlComment = new XmlComment(runtime, klazz);
|
||||
try {
|
||||
XmlComment clone = (XmlComment) xmlComment.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlComment(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_DOCUMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlDocument xmlDocument = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlDocument == null) xmlDocument = new XmlDocument(runtime, klazz);
|
||||
try {
|
||||
XmlDocument clone = (XmlDocument) xmlDocument.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlDocument(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_DOCUMENT_FRAGMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlDocumentFragment xmlDocumentFragment = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlDocumentFragment == null) xmlDocumentFragment = new XmlDocumentFragment(runtime, klazz);
|
||||
try {
|
||||
XmlDocumentFragment clone = (XmlDocumentFragment)xmlDocumentFragment.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlDocumentFragment(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_DTD_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlDtd xmlDtd = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlDtd == null) xmlDtd = new XmlDtd(runtime, klazz);
|
||||
try {
|
||||
XmlDtd clone = (XmlDtd)xmlDtd.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlDtd(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_ELEMENT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlElement xmlElement = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlElement == null) xmlElement = new XmlElement(runtime, klazz);
|
||||
try {
|
||||
XmlElement clone = (XmlElement)xmlElement.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlElement(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_ELEMENT_DECL_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlElementDecl xmlElementDecl = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlElementDecl == null) xmlElementDecl = new XmlElementDecl(runtime, klazz);
|
||||
try {
|
||||
XmlElementDecl clone = (XmlElementDecl)xmlElementDecl.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlElementDecl(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_ENTITY_REFERENCE_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlEntityReference xmlEntityRef = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlEntityRef == null) xmlEntityRef = new XmlEntityReference(runtime, klazz);
|
||||
try {
|
||||
XmlEntityReference clone = (XmlEntityReference)xmlEntityRef.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlEntityReference(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_NAMESPACE_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlNamespace xmlNamespace = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlNamespace == null) xmlNamespace = new XmlNamespace(runtime, klazz);
|
||||
try {
|
||||
XmlNamespace clone = (XmlNamespace) xmlNamespace.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlNamespace(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_NODE_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlNode xmlNode = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlNode == null) xmlNode = new XmlNode(runtime, klazz);
|
||||
try {
|
||||
XmlNode clone = (XmlNode) xmlNode.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlNode(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_NODESET_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlNodeSet xmlNodeSet = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlNodeSet == null) xmlNodeSet = new XmlNodeSet(runtime, klazz);
|
||||
try {
|
||||
XmlNodeSet clone = (XmlNodeSet) xmlNodeSet.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
xmlNodeSet = new XmlNodeSet(runtime, klazz);
|
||||
xmlNodeSet.setNodes(RubyArray.newEmptyArray(runtime));
|
||||
return xmlNodeSet;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_PROCESSING_INSTRUCTION_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlProcessingInstruction xmlProcessingInstruction = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlProcessingInstruction == null) xmlProcessingInstruction = new XmlProcessingInstruction(runtime, klazz);
|
||||
try {
|
||||
XmlProcessingInstruction clone = (XmlProcessingInstruction)xmlProcessingInstruction.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlProcessingInstruction(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_READER_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlReader xmlReader = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlReader == null) xmlReader = new XmlReader(runtime, klazz);
|
||||
try {
|
||||
XmlReader clone = (XmlReader) xmlReader.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
xmlReader = new XmlReader(runtime, klazz);
|
||||
return xmlReader;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator XML_ATTRIBUTE_DECL_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new XmlAttributeDecl(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator XML_ENTITY_DECL_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new XmlEntityDecl(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator XML_ELEMENT_CONTENT_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
throw runtime.newNotImplementedError("not implemented");
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_RELAXNG_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlRelaxng xmlRelaxng = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlRelaxng == null) xmlRelaxng = new XmlRelaxng(runtime, klazz);
|
||||
try {
|
||||
XmlRelaxng clone = (XmlRelaxng) xmlRelaxng.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlRelaxng(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_SAXPARSER_CONTEXT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlSaxParserContext xmlSaxParserContext = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlSaxParserContext == null) xmlSaxParserContext = new XmlSaxParserContext(runtime, klazz);
|
||||
try {
|
||||
XmlSaxParserContext clone = (XmlSaxParserContext) xmlSaxParserContext.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlSaxParserContext(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static ObjectAllocator XML_SAXPUSHPARSER_ALLOCATOR = new ObjectAllocator() {
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
return new XmlSaxPushParser(runtime, klazz);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_SCHEMA_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlSchema xmlSchema = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlSchema == null) xmlSchema = new XmlSchema(runtime, klazz);
|
||||
try {
|
||||
XmlSchema clone = (XmlSchema) xmlSchema.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlSchema(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_SYNTAXERROR_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlSyntaxError xmlSyntaxError = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlSyntaxError == null) xmlSyntaxError = new XmlSyntaxError(runtime, klazz);
|
||||
try {
|
||||
XmlSyntaxError clone = (XmlSyntaxError) xmlSyntaxError.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlSyntaxError(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static final ObjectAllocator XML_TEXT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlText xmlText = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlText == null) xmlText = new XmlText(runtime, klazz);
|
||||
try {
|
||||
XmlText clone = (XmlText) xmlText.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlText(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XML_XPATHCONTEXT_ALLOCATOR = new ObjectAllocator() {
|
||||
private XmlXpathContext xmlXpathContext = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xmlXpathContext == null) xmlXpathContext = new XmlXpathContext(runtime, klazz);
|
||||
try {
|
||||
XmlXpathContext clone = (XmlXpathContext) xmlXpathContext.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlXpathContext(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ObjectAllocator XSLT_STYLESHEET_ALLOCATOR = new ObjectAllocator() {
|
||||
private XsltStylesheet xsltStylesheet = null;
|
||||
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
|
||||
if (xsltStylesheet == null) xsltStylesheet = new XsltStylesheet(runtime, klazz);
|
||||
try {
|
||||
XsltStylesheet clone = (XsltStylesheet) xsltStylesheet.clone();
|
||||
clone.setMetaClass(klazz);
|
||||
return clone;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
return new XmlText(runtime, klazz);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
872
samples/java/clojure-type.java
Normal file
872
samples/java/clojure-type.java
Normal file
@@ -0,0 +1,872 @@
|
||||
/***
|
||||
* ASM: a very small and fast Java bytecode manipulation framework
|
||||
* Copyright (c) 2000-2005 INRIA, France Telecom
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of the copyright holders 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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 clojure.asm;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* A Java type. This class can be used to make it easier to manipulate type and
|
||||
* method descriptors.
|
||||
*
|
||||
* @author Eric Bruneton
|
||||
* @author Chris Nokleberg
|
||||
*/
|
||||
public class Type{
|
||||
|
||||
/**
|
||||
* The sort of the <tt>void</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int VOID = 0;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int BOOLEAN = 1;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>char</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int CHAR = 2;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>byte</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int BYTE = 3;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>short</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int SHORT = 4;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>int</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int INT = 5;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>float</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int FLOAT = 6;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>long</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int LONG = 7;
|
||||
|
||||
/**
|
||||
* The sort of the <tt>double</tt> type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int DOUBLE = 8;
|
||||
|
||||
/**
|
||||
* The sort of array reference types. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int ARRAY = 9;
|
||||
|
||||
/**
|
||||
* The sort of object reference type. See {@link #getSort getSort}.
|
||||
*/
|
||||
public final static int OBJECT = 10;
|
||||
|
||||
/**
|
||||
* The <tt>void</tt> type.
|
||||
*/
|
||||
public final static Type VOID_TYPE = new Type(VOID);
|
||||
|
||||
/**
|
||||
* The <tt>boolean</tt> type.
|
||||
*/
|
||||
public final static Type BOOLEAN_TYPE = new Type(BOOLEAN);
|
||||
|
||||
/**
|
||||
* The <tt>char</tt> type.
|
||||
*/
|
||||
public final static Type CHAR_TYPE = new Type(CHAR);
|
||||
|
||||
/**
|
||||
* The <tt>byte</tt> type.
|
||||
*/
|
||||
public final static Type BYTE_TYPE = new Type(BYTE);
|
||||
|
||||
/**
|
||||
* The <tt>short</tt> type.
|
||||
*/
|
||||
public final static Type SHORT_TYPE = new Type(SHORT);
|
||||
|
||||
/**
|
||||
* The <tt>int</tt> type.
|
||||
*/
|
||||
public final static Type INT_TYPE = new Type(INT);
|
||||
|
||||
/**
|
||||
* The <tt>float</tt> type.
|
||||
*/
|
||||
public final static Type FLOAT_TYPE = new Type(FLOAT);
|
||||
|
||||
/**
|
||||
* The <tt>long</tt> type.
|
||||
*/
|
||||
public final static Type LONG_TYPE = new Type(LONG);
|
||||
|
||||
/**
|
||||
* The <tt>double</tt> type.
|
||||
*/
|
||||
public final static Type DOUBLE_TYPE = new Type(DOUBLE);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Fields
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The sort of this Java type.
|
||||
*/
|
||||
private final int sort;
|
||||
|
||||
/**
|
||||
* A buffer containing the descriptor of this Java type. This field is only
|
||||
* used for reference types.
|
||||
*/
|
||||
private char[] buf;
|
||||
|
||||
/**
|
||||
* The offset of the descriptor of this Java type in {@link #buf buf}. This
|
||||
* field is only used for reference types.
|
||||
*/
|
||||
private int off;
|
||||
|
||||
/**
|
||||
* The length of the descriptor of this Java type.
|
||||
*/
|
||||
private int len;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Constructors
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a primitive type.
|
||||
*
|
||||
* @param sort the sort of the primitive type to be constructed.
|
||||
*/
|
||||
private Type(final int sort){
|
||||
this.sort = sort;
|
||||
this.len = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a reference type.
|
||||
*
|
||||
* @param sort the sort of the reference type to be constructed.
|
||||
* @param buf a buffer containing the descriptor of the previous type.
|
||||
* @param off the offset of this descriptor in the previous buffer.
|
||||
* @param len the length of this descriptor.
|
||||
*/
|
||||
private Type(final int sort, final char[] buf, final int off, final int len){
|
||||
this.sort = sort;
|
||||
this.buf = buf;
|
||||
this.off = off;
|
||||
this.len = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the given type descriptor.
|
||||
*
|
||||
* @param typeDescriptor a type descriptor.
|
||||
* @return the Java type corresponding to the given type descriptor.
|
||||
*/
|
||||
public static Type getType(final String typeDescriptor){
|
||||
return getType(typeDescriptor.toCharArray(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the given class.
|
||||
*
|
||||
* @param c a class.
|
||||
* @return the Java type corresponding to the given class.
|
||||
*/
|
||||
public static Type getType(final Class c){
|
||||
if(c.isPrimitive())
|
||||
{
|
||||
if(c == Integer.TYPE)
|
||||
{
|
||||
return INT_TYPE;
|
||||
}
|
||||
else if(c == Void.TYPE)
|
||||
{
|
||||
return VOID_TYPE;
|
||||
}
|
||||
else if(c == Boolean.TYPE)
|
||||
{
|
||||
return BOOLEAN_TYPE;
|
||||
}
|
||||
else if(c == Byte.TYPE)
|
||||
{
|
||||
return BYTE_TYPE;
|
||||
}
|
||||
else if(c == Character.TYPE)
|
||||
{
|
||||
return CHAR_TYPE;
|
||||
}
|
||||
else if(c == Short.TYPE)
|
||||
{
|
||||
return SHORT_TYPE;
|
||||
}
|
||||
else if(c == Double.TYPE)
|
||||
{
|
||||
return DOUBLE_TYPE;
|
||||
}
|
||||
else if(c == Float.TYPE)
|
||||
{
|
||||
return FLOAT_TYPE;
|
||||
}
|
||||
else /* if (c == Long.TYPE) */
|
||||
{
|
||||
return LONG_TYPE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return getType(getDescriptor(c));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Type#OBJECT} type for the given internal class name.
|
||||
* This is a shortcut method for <code>Type.getType("L"+name+";")</code>.
|
||||
* <i>Note that opposed to {@link Type#getType(String)}, this method takes
|
||||
* internal class names and not class descriptor.</i>
|
||||
*
|
||||
* @param name an internal class name.
|
||||
* @return the the {@link Type#OBJECT} type for the given class name.
|
||||
*/
|
||||
public static Type getObjectType(String name){
|
||||
int l = name.length();
|
||||
char[] buf = new char[l + 2];
|
||||
buf[0] = 'L';
|
||||
buf[l + 1] = ';';
|
||||
name.getChars(0, l, buf, 1);
|
||||
return new Type(OBJECT, buf, 0, l + 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java types corresponding to the argument types of the given
|
||||
* method descriptor.
|
||||
*
|
||||
* @param methodDescriptor a method descriptor.
|
||||
* @return the Java types corresponding to the argument types of the given
|
||||
* method descriptor.
|
||||
*/
|
||||
public static Type[] getArgumentTypes(final String methodDescriptor){
|
||||
char[] buf = methodDescriptor.toCharArray();
|
||||
int off = 1;
|
||||
int size = 0;
|
||||
while(true)
|
||||
{
|
||||
char car = buf[off++];
|
||||
if(car == ')')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(car == 'L')
|
||||
{
|
||||
while(buf[off++] != ';')
|
||||
{
|
||||
}
|
||||
++size;
|
||||
}
|
||||
else if(car != '[')
|
||||
{
|
||||
++size;
|
||||
}
|
||||
}
|
||||
Type[] args = new Type[size];
|
||||
off = 1;
|
||||
size = 0;
|
||||
while(buf[off] != ')')
|
||||
{
|
||||
args[size] = getType(buf, off);
|
||||
off += args[size].len;
|
||||
size += 1;
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java types corresponding to the argument types of the given
|
||||
* method.
|
||||
*
|
||||
* @param method a method.
|
||||
* @return the Java types corresponding to the argument types of the given
|
||||
* method.
|
||||
*/
|
||||
public static Type[] getArgumentTypes(final Method method){
|
||||
Class[] classes = method.getParameterTypes();
|
||||
Type[] types = new Type[classes.length];
|
||||
for(int i = classes.length - 1; i >= 0; --i)
|
||||
{
|
||||
types[i] = getType(classes[i]);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the return type of the given
|
||||
* method descriptor.
|
||||
*
|
||||
* @param methodDescriptor a method descriptor.
|
||||
* @return the Java type corresponding to the return type of the given
|
||||
* method descriptor.
|
||||
*/
|
||||
public static Type getReturnType(final String methodDescriptor){
|
||||
char[] buf = methodDescriptor.toCharArray();
|
||||
return getType(buf, methodDescriptor.indexOf(')') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the return type of the given
|
||||
* method.
|
||||
*
|
||||
* @param method a method.
|
||||
* @return the Java type corresponding to the return type of the given
|
||||
* method.
|
||||
*/
|
||||
public static Type getReturnType(final Method method){
|
||||
return getType(method.getReturnType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type corresponding to the given type descriptor.
|
||||
*
|
||||
* @param buf a buffer containing a type descriptor.
|
||||
* @param off the offset of this descriptor in the previous buffer.
|
||||
* @return the Java type corresponding to the given type descriptor.
|
||||
*/
|
||||
private static Type getType(final char[] buf, final int off){
|
||||
int len;
|
||||
switch(buf[off])
|
||||
{
|
||||
case'V':
|
||||
return VOID_TYPE;
|
||||
case'Z':
|
||||
return BOOLEAN_TYPE;
|
||||
case'C':
|
||||
return CHAR_TYPE;
|
||||
case'B':
|
||||
return BYTE_TYPE;
|
||||
case'S':
|
||||
return SHORT_TYPE;
|
||||
case'I':
|
||||
return INT_TYPE;
|
||||
case'F':
|
||||
return FLOAT_TYPE;
|
||||
case'J':
|
||||
return LONG_TYPE;
|
||||
case'D':
|
||||
return DOUBLE_TYPE;
|
||||
case'[':
|
||||
len = 1;
|
||||
while(buf[off + len] == '[')
|
||||
{
|
||||
++len;
|
||||
}
|
||||
if(buf[off + len] == 'L')
|
||||
{
|
||||
++len;
|
||||
while(buf[off + len] != ';')
|
||||
{
|
||||
++len;
|
||||
}
|
||||
}
|
||||
return new Type(ARRAY, buf, off, len + 1);
|
||||
// case 'L':
|
||||
default:
|
||||
len = 1;
|
||||
while(buf[off + len] != ';')
|
||||
{
|
||||
++len;
|
||||
}
|
||||
return new Type(OBJECT, buf, off, len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Accessors
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the sort of this Java type.
|
||||
*
|
||||
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN},
|
||||
* {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT},
|
||||
* {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
|
||||
* {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY} or
|
||||
* {@link #OBJECT OBJECT}.
|
||||
*/
|
||||
public int getSort(){
|
||||
return sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of dimensions of this array type. This method should
|
||||
* only be used for an array type.
|
||||
*
|
||||
* @return the number of dimensions of this array type.
|
||||
*/
|
||||
public int getDimensions(){
|
||||
int i = 1;
|
||||
while(buf[off + i] == '[')
|
||||
{
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the elements of this array type. This method should
|
||||
* only be used for an array type.
|
||||
*
|
||||
* @return Returns the type of the elements of this array type.
|
||||
*/
|
||||
public Type getElementType(){
|
||||
return getType(buf, off + getDimensions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the class corresponding to this type.
|
||||
*
|
||||
* @return the fully qualified name of the class corresponding to this type.
|
||||
*/
|
||||
public String getClassName(){
|
||||
switch(sort)
|
||||
{
|
||||
case VOID:
|
||||
return "void";
|
||||
case BOOLEAN:
|
||||
return "boolean";
|
||||
case CHAR:
|
||||
return "char";
|
||||
case BYTE:
|
||||
return "byte";
|
||||
case SHORT:
|
||||
return "short";
|
||||
case INT:
|
||||
return "int";
|
||||
case FLOAT:
|
||||
return "float";
|
||||
case LONG:
|
||||
return "long";
|
||||
case DOUBLE:
|
||||
return "double";
|
||||
case ARRAY:
|
||||
StringBuffer b = new StringBuffer(getElementType().getClassName());
|
||||
for(int i = getDimensions(); i > 0; --i)
|
||||
{
|
||||
b.append("[]");
|
||||
}
|
||||
return b.toString();
|
||||
// case OBJECT:
|
||||
default:
|
||||
return new String(buf, off + 1, len - 2).replace('/', '.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internal name of the class corresponding to this object type.
|
||||
* The internal name of a class is its fully qualified name, where '.' are
|
||||
* replaced by '/'. This method should only be used for an object type.
|
||||
*
|
||||
* @return the internal name of the class corresponding to this object type.
|
||||
*/
|
||||
public String getInternalName(){
|
||||
return new String(buf, off + 1, len - 2);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Conversion to type descriptors
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to this Java type.
|
||||
*
|
||||
* @return the descriptor corresponding to this Java type.
|
||||
*/
|
||||
public String getDescriptor(){
|
||||
StringBuffer buf = new StringBuffer();
|
||||
getDescriptor(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to the given argument and return
|
||||
* types.
|
||||
*
|
||||
* @param returnType the return type of the method.
|
||||
* @param argumentTypes the argument types of the method.
|
||||
* @return the descriptor corresponding to the given argument and return
|
||||
* types.
|
||||
*/
|
||||
public static String getMethodDescriptor(
|
||||
final Type returnType,
|
||||
final Type[] argumentTypes){
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append('(');
|
||||
for(int i = 0; i < argumentTypes.length; ++i)
|
||||
{
|
||||
argumentTypes[i].getDescriptor(buf);
|
||||
}
|
||||
buf.append(')');
|
||||
returnType.getDescriptor(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the descriptor corresponding to this Java type to the given
|
||||
* string buffer.
|
||||
*
|
||||
* @param buf the string buffer to which the descriptor must be appended.
|
||||
*/
|
||||
private void getDescriptor(final StringBuffer buf){
|
||||
switch(sort)
|
||||
{
|
||||
case VOID:
|
||||
buf.append('V');
|
||||
return;
|
||||
case BOOLEAN:
|
||||
buf.append('Z');
|
||||
return;
|
||||
case CHAR:
|
||||
buf.append('C');
|
||||
return;
|
||||
case BYTE:
|
||||
buf.append('B');
|
||||
return;
|
||||
case SHORT:
|
||||
buf.append('S');
|
||||
return;
|
||||
case INT:
|
||||
buf.append('I');
|
||||
return;
|
||||
case FLOAT:
|
||||
buf.append('F');
|
||||
return;
|
||||
case LONG:
|
||||
buf.append('J');
|
||||
return;
|
||||
case DOUBLE:
|
||||
buf.append('D');
|
||||
return;
|
||||
// case ARRAY:
|
||||
// case OBJECT:
|
||||
default:
|
||||
buf.append(this.buf, off, len);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Direct conversion from classes to type descriptors,
|
||||
// without intermediate Type objects
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the internal name of the given class. The internal name of a
|
||||
* class is its fully qualified name, where '.' are replaced by '/'.
|
||||
*
|
||||
* @param c an object class.
|
||||
* @return the internal name of the given class.
|
||||
*/
|
||||
public static String getInternalName(final Class c){
|
||||
return c.getName().replace('.', '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to the given Java type.
|
||||
*
|
||||
* @param c an object class, a primitive class or an array class.
|
||||
* @return the descriptor corresponding to the given class.
|
||||
*/
|
||||
public static String getDescriptor(final Class c){
|
||||
StringBuffer buf = new StringBuffer();
|
||||
getDescriptor(buf, c);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to the given constructor.
|
||||
*
|
||||
* @param c a {@link Constructor Constructor} object.
|
||||
* @return the descriptor of the given constructor.
|
||||
*/
|
||||
public static String getConstructorDescriptor(final Constructor c){
|
||||
Class[] parameters = c.getParameterTypes();
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append('(');
|
||||
for(int i = 0; i < parameters.length; ++i)
|
||||
{
|
||||
getDescriptor(buf, parameters[i]);
|
||||
}
|
||||
return buf.append(")V").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descriptor corresponding to the given method.
|
||||
*
|
||||
* @param m a {@link Method Method} object.
|
||||
* @return the descriptor of the given method.
|
||||
*/
|
||||
public static String getMethodDescriptor(final Method m){
|
||||
Class[] parameters = m.getParameterTypes();
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append('(');
|
||||
for(int i = 0; i < parameters.length; ++i)
|
||||
{
|
||||
getDescriptor(buf, parameters[i]);
|
||||
}
|
||||
buf.append(')');
|
||||
getDescriptor(buf, m.getReturnType());
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the descriptor of the given class to the given string buffer.
|
||||
*
|
||||
* @param buf the string buffer to which the descriptor must be appended.
|
||||
* @param c the class whose descriptor must be computed.
|
||||
*/
|
||||
private static void getDescriptor(final StringBuffer buf, final Class c){
|
||||
Class d = c;
|
||||
while(true)
|
||||
{
|
||||
if(d.isPrimitive())
|
||||
{
|
||||
char car;
|
||||
if(d == Integer.TYPE)
|
||||
{
|
||||
car = 'I';
|
||||
}
|
||||
else if(d == Void.TYPE)
|
||||
{
|
||||
car = 'V';
|
||||
}
|
||||
else if(d == Boolean.TYPE)
|
||||
{
|
||||
car = 'Z';
|
||||
}
|
||||
else if(d == Byte.TYPE)
|
||||
{
|
||||
car = 'B';
|
||||
}
|
||||
else if(d == Character.TYPE)
|
||||
{
|
||||
car = 'C';
|
||||
}
|
||||
else if(d == Short.TYPE)
|
||||
{
|
||||
car = 'S';
|
||||
}
|
||||
else if(d == Double.TYPE)
|
||||
{
|
||||
car = 'D';
|
||||
}
|
||||
else if(d == Float.TYPE)
|
||||
{
|
||||
car = 'F';
|
||||
}
|
||||
else /* if (d == Long.TYPE) */
|
||||
{
|
||||
car = 'J';
|
||||
}
|
||||
buf.append(car);
|
||||
return;
|
||||
}
|
||||
else if(d.isArray())
|
||||
{
|
||||
buf.append('[');
|
||||
d = d.getComponentType();
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.append('L');
|
||||
String name = d.getName();
|
||||
int len = name.length();
|
||||
for(int i = 0; i < len; ++i)
|
||||
{
|
||||
char car = name.charAt(i);
|
||||
buf.append(car == '.' ? '/' : car);
|
||||
}
|
||||
buf.append(';');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Corresponding size and opcodes
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the size of values of this type.
|
||||
*
|
||||
* @return the size of values of this type, i.e., 2 for <tt>long</tt> and
|
||||
* <tt>double</tt>, and 1 otherwise.
|
||||
*/
|
||||
public int getSize(){
|
||||
return sort == LONG || sort == DOUBLE ? 2 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JVM instruction opcode adapted to this Java type.
|
||||
*
|
||||
* @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
|
||||
* ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
|
||||
* ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
|
||||
* @return an opcode that is similar to the given opcode, but adapted to
|
||||
* this Java type. For example, if this type is <tt>float</tt> and
|
||||
* <tt>opcode</tt> is IRETURN, this method returns FRETURN.
|
||||
*/
|
||||
public int getOpcode(final int opcode){
|
||||
if(opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE)
|
||||
{
|
||||
switch(sort)
|
||||
{
|
||||
case BOOLEAN:
|
||||
case BYTE:
|
||||
return opcode + 5;
|
||||
case CHAR:
|
||||
return opcode + 6;
|
||||
case SHORT:
|
||||
return opcode + 7;
|
||||
case INT:
|
||||
return opcode;
|
||||
case FLOAT:
|
||||
return opcode + 2;
|
||||
case LONG:
|
||||
return opcode + 1;
|
||||
case DOUBLE:
|
||||
return opcode + 3;
|
||||
// case ARRAY:
|
||||
// case OBJECT:
|
||||
default:
|
||||
return opcode + 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(sort)
|
||||
{
|
||||
case VOID:
|
||||
return opcode + 5;
|
||||
case BOOLEAN:
|
||||
case CHAR:
|
||||
case BYTE:
|
||||
case SHORT:
|
||||
case INT:
|
||||
return opcode;
|
||||
case FLOAT:
|
||||
return opcode + 2;
|
||||
case LONG:
|
||||
return opcode + 1;
|
||||
case DOUBLE:
|
||||
return opcode + 3;
|
||||
// case ARRAY:
|
||||
// case OBJECT:
|
||||
default:
|
||||
return opcode + 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Equals, hashCode and toString
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Tests if the given object is equal to this type.
|
||||
*
|
||||
* @param o the object to be compared to this type.
|
||||
* @return <tt>true</tt> if the given object is equal to this type.
|
||||
*/
|
||||
public boolean equals(final Object o){
|
||||
if(this == o)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(!(o instanceof Type))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Type t = (Type) o;
|
||||
if(sort != t.sort)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(sort == Type.OBJECT || sort == Type.ARRAY)
|
||||
{
|
||||
if(len != t.len)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for(int i = off, j = t.off, end = i + len; i < end; i++, j++)
|
||||
{
|
||||
if(buf[i] != t.buf[j])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code value for this type.
|
||||
*
|
||||
* @return a hash code value for this type.
|
||||
*/
|
||||
public int hashCode(){
|
||||
int hc = 13 * sort;
|
||||
if(sort == Type.OBJECT || sort == Type.ARRAY)
|
||||
{
|
||||
for(int i = off, end = i + len; i < end; i++)
|
||||
{
|
||||
hc = 17 * (hc + buf[i]);
|
||||
}
|
||||
}
|
||||
return hc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this type.
|
||||
*
|
||||
* @return the descriptor of this type.
|
||||
*/
|
||||
public String toString(){
|
||||
return getDescriptor();
|
||||
}
|
||||
}
|
||||
197
samples/java/clojure-util.java
Normal file
197
samples/java/clojure-util.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Copyright (c) Rich Hickey. All rights reserved.
|
||||
* The use and distribution terms for this software are covered by the
|
||||
* Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
||||
* which can be found in the file epl-v10.html at the root of this distribution.
|
||||
* By using this software in any fashion, you are agreeing to be bound by
|
||||
* the terms of this license.
|
||||
* You must not remove this notice, or any other, from this software.
|
||||
**/
|
||||
|
||||
/* rich Apr 19, 2008 */
|
||||
|
||||
package clojure.lang;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
|
||||
public class Util{
|
||||
static public boolean equiv(Object k1, Object k2){
|
||||
if(k1 == k2)
|
||||
return true;
|
||||
if(k1 != null)
|
||||
{
|
||||
if(k1 instanceof Number && k2 instanceof Number)
|
||||
return Numbers.equal((Number)k1, (Number)k2);
|
||||
else if(k1 instanceof IPersistentCollection || k2 instanceof IPersistentCollection)
|
||||
return pcequiv(k1,k2);
|
||||
return k1.equals(k2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public boolean equiv(long k1, long k2){
|
||||
return k1 == k2;
|
||||
}
|
||||
|
||||
static public boolean equiv(Object k1, long k2){
|
||||
return equiv(k1, (Object)k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(long k1, Object k2){
|
||||
return equiv((Object)k1, k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(double k1, double k2){
|
||||
return k1 == k2;
|
||||
}
|
||||
|
||||
static public boolean equiv(Object k1, double k2){
|
||||
return equiv(k1, (Object)k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(double k1, Object k2){
|
||||
return equiv((Object)k1, k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(boolean k1, boolean k2){
|
||||
return k1 == k2;
|
||||
}
|
||||
|
||||
static public boolean equiv(Object k1, boolean k2){
|
||||
return equiv(k1, (Object)k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(boolean k1, Object k2){
|
||||
return equiv((Object)k1, k2);
|
||||
}
|
||||
|
||||
static public boolean equiv(char c1, char c2) {
|
||||
return c1 == c2;
|
||||
}
|
||||
|
||||
static public boolean pcequiv(Object k1, Object k2){
|
||||
if(k1 instanceof IPersistentCollection)
|
||||
return ((IPersistentCollection)k1).equiv(k2);
|
||||
return ((IPersistentCollection)k2).equiv(k1);
|
||||
}
|
||||
|
||||
static public boolean equals(Object k1, Object k2){
|
||||
if(k1 == k2)
|
||||
return true;
|
||||
return k1 != null && k1.equals(k2);
|
||||
}
|
||||
|
||||
static public boolean identical(Object k1, Object k2){
|
||||
return k1 == k2;
|
||||
}
|
||||
|
||||
static public Class classOf(Object x){
|
||||
if(x != null)
|
||||
return x.getClass();
|
||||
return null;
|
||||
}
|
||||
|
||||
static public int compare(Object k1, Object k2){
|
||||
if(k1 == k2)
|
||||
return 0;
|
||||
if(k1 != null)
|
||||
{
|
||||
if(k2 == null)
|
||||
return 1;
|
||||
if(k1 instanceof Number)
|
||||
return Numbers.compare((Number) k1, (Number) k2);
|
||||
return ((Comparable) k1).compareTo(k2);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static public int hash(Object o){
|
||||
if(o == null)
|
||||
return 0;
|
||||
return o.hashCode();
|
||||
}
|
||||
|
||||
static public int hasheq(Object o){
|
||||
if(o == null)
|
||||
return 0;
|
||||
if(o instanceof Number)
|
||||
return Numbers.hasheq((Number)o);
|
||||
else if(o instanceof IHashEq)
|
||||
return ((IHashEq)o).hasheq();
|
||||
return o.hashCode();
|
||||
}
|
||||
|
||||
static public int hashCombine(int seed, int hash){
|
||||
//a la boost
|
||||
seed ^= hash + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
return seed;
|
||||
}
|
||||
|
||||
static public boolean isPrimitive(Class c){
|
||||
return c != null && c.isPrimitive() && !(c == Void.TYPE);
|
||||
}
|
||||
|
||||
static public boolean isInteger(Object x){
|
||||
return x instanceof Integer
|
||||
|| x instanceof Long
|
||||
|| x instanceof BigInt
|
||||
|| x instanceof BigInteger;
|
||||
}
|
||||
|
||||
static public Object ret1(Object ret, Object nil){
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public ISeq ret1(ISeq ret, Object nil){
|
||||
return ret;
|
||||
}
|
||||
|
||||
static public <K,V> void clearCache(ReferenceQueue rq, ConcurrentHashMap<K, Reference<V>> cache){
|
||||
//cleanup any dead entries
|
||||
if(rq.poll() != null)
|
||||
{
|
||||
while(rq.poll() != null)
|
||||
;
|
||||
for(Map.Entry<K, Reference<V>> e : cache.entrySet())
|
||||
{
|
||||
Reference<V> val = e.getValue();
|
||||
if(val != null && val.get() == null)
|
||||
cache.remove(e.getKey(), val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public RuntimeException runtimeException(String s){
|
||||
return new RuntimeException(s);
|
||||
}
|
||||
|
||||
static public RuntimeException runtimeException(String s, Throwable e){
|
||||
return new RuntimeException(s, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw even checked exceptions without being required
|
||||
* to declare them or catch them. Suggested idiom:
|
||||
* <p>
|
||||
* <code>throw sneakyThrow( some exception );</code>
|
||||
*/
|
||||
static public RuntimeException sneakyThrow(Throwable t) {
|
||||
// http://www.mail-archive.com/javaposse@googlegroups.com/msg05984.html
|
||||
if (t == null)
|
||||
throw new NullPointerException();
|
||||
Util.<RuntimeException>sneakyThrow0(t);
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static private <T extends Throwable> void sneakyThrow0(Throwable t) throws T {
|
||||
throw (T) t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user