⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 astreference.java

📁 velocity 的脚本语言的全部代码集合
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
     *
     *  @see ASTSetDirective
     *
     *  @param context context object containing this reference
     *  @param value Object to set as value
     *  @return true if successful, false otherwise
     */
    public boolean setValue( InternalContextAdapter context, Object value)
      throws MethodInvocationException
    {
        if (jjtGetNumChildren() == 0)
        {
            context.put(rootString, value);
            return true;
        }

        /*
         *  The rootOfIntrospection is the object we will
         *  retrieve from the Context. This is the base
         *  object we will apply reflection to.
         */

        Object result = getVariableValue(context, rootString);

        if (result == null)
        {
            rsvc.error(new ReferenceException("reference set : template = "
                    + context.getCurrentTemplateName(), this));
            return false;
        }

        /*
         * How many child nodes do we have?
         */

        for (int i = 0; i < numChildren - 1; i++)
        {
            result = jjtGetChild(i).execute(result, context);

            if (result == null)
            {
                rsvc.error(new ReferenceException("reference set : template = "
                        + context.getCurrentTemplateName(), this));
                return false;
            }
        }

        /*
         *  We support two ways of setting the value in a #set($ref.foo = $value ) :
         *  1) ref.setFoo( value )
         *  2) ref,put("foo", value ) to parallel the get() map introspection
         */

        try
        {
            VelPropertySet vs =
                    rsvc.getUberspect().getPropertySet(result, identifier,
                            value, uberInfo);

            if (vs == null)
                return false;

            vs.invoke(result, value);
        }
        catch(InvocationTargetException ite)
        {
            /*
             *  this is possible
             */

            throw  new MethodInvocationException(
                "ASTReference : Invocation of method '"
                + identifier + "' in  " + result.getClass()
                + " threw exception "
                + ite.getTargetException().getClass(),
               ite.getTargetException(), identifier );
        }
        catch(Exception e)
        {
            /*
             *  maybe a security exception?
             */
            rsvc.error("ASTReference setValue() : exception : " + e
                                  + " template = " + context.getCurrentTemplateName()
                                  + " [" + this.getLine() + "," + this.getColumn() + "]");
            return false;
         }

        return true;
    }

    private String getRoot()
    {
        Token t = getFirstToken();

        /*
         *  we have a special case where something like
         *  $(\\)*!, where the user want's to see something
         *  like $!blargh in the output, but the ! prevents it from showing.
         *  I think that at this point, this isn't a reference.
         */

        /* so, see if we have "\\!" */

        int slashbang = t.image.indexOf("\\!");

        if (slashbang != -1)
        {
            /*
             *  lets do all the work here.  I would argue that if this occurrs,
             *  it's not a reference at all, so preceeding \ characters in front
             *  of the $ are just schmoo.  So we just do the escape processing
             *  trick (even | odd) and move on.  This kind of breaks the rule
             *  pattern of $ and # but '!' really tosses a wrench into things.
             */

             /*
              *  count the escapes : even # -> not escaped, odd -> escaped
              */

            int i = 0;
            int len = t.image.length();

            i = t.image.indexOf('$');

            if (i == -1)
            {
                /* yikes! */
                rsvc.error("ASTReference.getRoot() : internal error : "
                            + "no $ found for slashbang.");
                computableReference = false;
                nullString = t.image;
                return nullString;
            }

            while (i < len && t.image.charAt(i) != '\\')
            {
                i++;
            }

            /*  ok, i is the first \ char */

            int start = i;
            int count = 0;

            while (i < len && t.image.charAt(i++) == '\\')
            {
                count++;
            }

            /*
             *  now construct the output string.  We really don't care about
             *  leading  slashes as this is not a reference.  It's quasi-schmoo
             */

            nullString = t.image.substring(0,start); // prefix up to the first
            nullString += t.image.substring(start, start + count-1 ); // get the slashes
            nullString += t.image.substring(start+count); // and the rest, including the

            /*
             *  this isn't a valid reference, so lets short circuit the value
             *  and set calcs
             */

            computableReference = false;

            return nullString;
        }

        /*
         *  we need to see if this reference is escaped.  if so
         *  we will clean off the leading \'s and let the
         *  regular behavior determine if we should output this
         *  as \$foo or $foo later on in render(). Lazyness..
         */

        escaped = false;

        if (t.image.startsWith("\\"))
        {
            /*
             *  count the escapes : even # -> not escaped, odd -> escaped
             */

            int i = 0;
            int len = t.image.length();

            while (i < len && t.image.charAt(i) == '\\')
            {
                i++;
            }

            if ((i % 2) != 0)
                escaped = true;

            if (i > 0)
                escPrefix = t.image.substring(0, i / 2 );

            t.image = t.image.substring(i);
        }

        /*
         *  Look for preceeding stuff like '#' and '$'
         *  and snip it off, except for the
         *  last $
         */

        int loc1 = t.image.lastIndexOf('$');

        /*
         *  if we have extra stuff, loc > 0
         *  ex. '#$foo' so attach that to
         *  the prefix.
         */
        if (loc1 > 0)
        {
            morePrefix = morePrefix + t.image.substring(0, loc1);
            t.image = t.image.substring(loc1);
        }

        /*
         *  Now it should be clean. Get the literal in case this reference
         *  isn't backed by the context at runtime, and then figure out what
         *  we are working with.
         */

        nullString = literal();

        if (t.image.startsWith("$!"))
        {
            referenceType = QUIET_REFERENCE;

            /*
             *  only if we aren't escaped do we want to null the output
             */

            if (!escaped)
                nullString = "";

            if (t.image.startsWith("$!{"))
            {
                /*
                 *  ex : $!{provider.Title}
                 */

                return t.next.image;
            }
            else
            {
                /*
                 *  ex : $!provider.Title
                 */

                return t.image.substring(2);
            }
        }
        else if (t.image.equals("${"))
        {
            /*
             *  ex : ${provider.Title}
             */

            referenceType = FORMAL_REFERENCE;
            return t.next.image;
        }
        else if (t.image.startsWith("$"))
        {
            /*
             *  just nip off the '$' so we have
             *  the root
             */

            referenceType = NORMAL_REFERENCE;
            return t.image.substring(1);
        }
        else
        {
            /*
             * this is a 'RUNT', which can happen in certain circumstances where
             *  the parser is fooled into believeing that an IDENTIFIER is a real
             *  reference.  Another 'dreaded' MORE hack :).
             */
            referenceType = RUNT;
            return t.image;
        }

    }

    public Object getVariableValue(Context context, String variable)
    {
        return context.get(variable);
    }


    /**
     *  Routine to allow the literal representation to be
     *  externally overridden.  Used now in the VM system
     *  to override a reference in a VM tree with the
     *  literal of the calling arg to make it work nicely
     *  when calling arg is null.  It seems a bit much, but
     *  does keep things consistant.
     *
     *  Note, you can only set the literal once...
     *
     *  @param literal String to render to when null
     */
    public void setLiteral(String literal)
    {
        /*
         * do only once
         */

        if( this.literal == null)
            this.literal = literal;
    }

    /**
     *  Override of the SimpleNode method literal()
     *  Returns the literal representation of the
     *  node.  Should be something like
     *  $<token>.
     */
    public String literal()
    {
        if (literal != null)
            return literal;

        return super.literal();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -