Hi Again!

When users are putting often the same long markup sequences, it may be useful to define "aliases".

Attached modifications allows to:

1) define aliases in jspwiki.properties. For instance:
  #Applications shortcuts
alias.citedby=[{ReferringPagesPlugin title='!Cited by:%n' exclude='Main,LeftMenu'}]

2) Call those alliases in pages: the syntax is the same than for variable inclusion but a "$" sign is added at the end.
  For instance: [{$citedby$}]
  The WikiMarkup inside the alias is interpreted.

The nice thing is also that you can change the definition of an Alias without changing the wiki pages...

Final note: \n is allowed in jspwiki.properties to indicate a end of line (\n\n for end of paragraph)

Attached source code is for 2.6.1. VariableContent.java is in the "parser" directory.

Have a nice day!

Christophe
/* 
    JSPWiki - a JSP-based WikiWiki clone.

    Copyright (C) 2001 Janne Jalkanen ([EMAIL PROTECTED])

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package com.ecyrd.jspwiki;

import java.security.Principal;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.ecyrd.jspwiki.filters.PageFilter;
import com.ecyrd.jspwiki.modules.InternalModule;

import com.ecyrd.jspwiki.render.RenderingManager;
import com.ecyrd.jspwiki.parser.MarkupParser;
import com.ecyrd.jspwiki.parser.WikiDocument;

/**
 *  Manages variables.  Variables are case-insensitive.  A list of all
 *  available variables is on a Wiki page called "WikiVariables".
 *
 *  @author Janne Jalkanen
 *  @since 1.9.20.
 */
public class VariableManager
{
    //private static Logger log = Logger.getLogger( VariableManager.class );
   
    // FIXME: These are probably obsolete.
    public static final String VAR_ERROR = "error";
    public static final String VAR_MSG   = "msg";
    
    /**
     *  Contains a list of those properties that shall never be shown.
     *  Put names here in lower case.
     */
    
    static final String[] THE_BIG_NO_NO_LIST = {
        "jspwiki.auth.masterpassword"
    };
    
    /**
     *  Creates a VariableManager object using the property list given.
     *  @param props The properties.
     */
    public VariableManager( Properties props )
    {
    }

    /**
     *  Returns true if the link is really command to insert
     *  a variable.
     *  <P>
     *  Currently we just check if the link starts with "{$".
     *  
     *  @param link The link text
     *  @return true, if this represents a variable link.
     */
    public static boolean isVariableLink( String link )
    {
        return link.startsWith("{$");
    }

    /**
     *  Parses the link and finds a value.  This is essentially used
     *  once [EMAIL PROTECTED] #isVariableLink(String)} has found that the link 
text
     *  actually contains a variable.  For example, you could pass in
     *  "{$username}" and get back "JanneJalkanen".
     *
     *  @param  context The WikiContext
     *  @param  link    The link text containing the variable name.
     *  @return The variable value.
     *  @throws IllegalArgumentException If the format is not valid (does not 
     *          start with "{$", is zero length, etc.)
     *  @throws NoSuchVariableException If a variable is not known.
     */
    public String parseAndGetValue( WikiContext context,
                                    String link )
        throws IllegalArgumentException,
               IOException,
               NoSuchVariableException
    {
        if( !link.startsWith("{$") )
            throw new IllegalArgumentException( "Link does not start with {$" );

        if( !link.endsWith("}") )
            throw new IllegalArgumentException( "Link does not end with }" );

        String varName = link.substring(2,link.length()-1);

        return getValue( context, varName.trim() );
    }

    /**
     *  This method does in-place expansion of any variables.  However,
     *  the expansion is not done twice, that is, a variable containing text 
$variable
     *  will not be expanded.
     *  <P>
     *  The variables should be in the same format ({$variablename} as in the 
web 
     *  pages.
     *
     *  @param context The WikiContext of the current page.
     *  @param source  The source string.
     *  @return The source string with variables expanded.
     */
    // FIXME: somewhat slow.
    public String expandVariables( WikiContext context,
                                   String      source )
    {
        StringBuffer result = new StringBuffer();

        for( int i = 0; i < source.length(); i++ )
        {
            if( source.charAt(i) == '{' )
            {
                if( i < source.length()-2 && source.charAt(i+1) == '$' )
                {
                    int end = source.indexOf( '}', i );

                    if( end != -1 )
                    {
                        String varname = source.substring( i+2, end );
                        String value;

                        try
                        {
                            value = getValue( context, varname );
                        }
                        catch( IOException e )
                        {
                            value = e.getMessage();
                        }
                        catch( NoSuchVariableException e )
                        {
                            value = e.getMessage();
                        }
                        catch( IllegalArgumentException e )
                        {
                            value = e.getMessage();
                        }

                        result.append( value );
                        i = end;
                        continue;
                    }
                }
                else
                {
                    result.append( '{' );
                }
            }
            else
            {
                result.append( source.charAt(i) );
            }
        }

        return result.toString();
    }
    
    // Probably this should be a method of WikiContext...
    private String makeHTML (WikiContext context, String wikitext) throws 
IOException
    {
        String result = "";

        RenderingManager mgr = context.getEngine().getRenderingManager();
        MarkupParser parser = mgr.getParser(context, wikitext);
        WikiDocument doc = parser.parse();
        result = mgr.getHTML( context, doc );
        return result;
    }

    /**
     *  Returns the value of a named variable.  See [EMAIL PROTECTED] 
#getValue(WikiContext, String)}.
     *  The only difference is that this method does not throw an exception, 
but it
     *  returns the given default value instead.
     *  
     *  @param context WikiContext
     *  @param varName The name of the variable
     *  @param defValue A default value.
     *  @return The variable value, or if not found, the default value.
     */
    public String getValue( WikiContext context, String varName, String 
defValue )
    {
        try
        {
            return getValue( context, varName );
        }
        catch( NoSuchVariableException e )
        {
            return defValue;
        }
        catch( IOException e )
        {
            return defValue;
        }
    }
    
    /**
     *  Returns a value of the named variable.  The resolving order is
     *  <ol>
     *    <li>Known "constant" name, such as "pagename", etc.  This is so
     *        that pages could not override certain constants.
     *    <li>WikiContext local variable.  This allows a programmer to
     *        set a parameter which cannot be overridden by user.
     *    <li>HTTP Session
     *    <li>HTTP Request parameters
     *    <li>WikiPage variable.  As set by the user with the SET directive.
     *    <li>jspwiki.properties
     *  </ol>
     *
     *  Use this method only whenever you really need to have a parameter that
     *  can be overridden by anyone using the wiki.
     *  
     *  @param context The WikiContext
     *  @param varName Name of the variable.
     *
     *  @return The variable value.
     *  
     *  @throws IllegalArgumentException If the name is somehow broken.
     *  @throws NoSuchVariableException If a variable is not known.
     */
    // FIXME: Currently a bit complicated.  Perhaps should use reflection
    //        or something to make an easy way of doing stuff.
    public String getValue( WikiContext context,
                            String      varName )
        throws IllegalArgumentException,
               IOException,
               NoSuchVariableException
    {
        if( varName == null )
            throw new IllegalArgumentException( "Null variable name." );

        if( varName.length() == 0 )
            throw new IllegalArgumentException( "Zero length variable name." );

        // Faster than doing equalsIgnoreCase()
        String name = varName.toLowerCase();

        for( int i = 0; i < THE_BIG_NO_NO_LIST.length; i++ )
        {
            if( name.equals(THE_BIG_NO_NO_LIST[i]) )
                return ""; // FIXME: Should this be something different?
        }
        
        if( name.equals("pagename") )
        {
            return context.getPage().getName();
        }
        else if( name.equals("applicationname") )
        {
            return context.getEngine().getApplicationName();
        }
        else if( name.equals("jspwikiversion") )
        {
            return Release.getVersionString();
        }
        else if( name.equals("encoding") )
        {
            return context.getEngine().getContentEncoding();
        }
        else if( name.equals("totalpages") )
        {
            return Integer.toString(context.getEngine().getPageCount());
        }
        else if( name.equals("pageprovider") )
        {
            return context.getEngine().getCurrentProvider();
        }
        else if( name.equals("pageproviderdescription") )
        {
            return context.getEngine().getCurrentProviderInfo();
        }
        else if( name.equals("attachmentprovider") )
        {
            WikiProvider p = 
context.getEngine().getAttachmentManager().getCurrentProvider();
            return (p != null) ? p.getClass().getName() : "-";
        }
        else if( name.equals("attachmentproviderdescription") )
        {
            WikiProvider p = 
context.getEngine().getAttachmentManager().getCurrentProvider();

            return (p != null) ? p.getProviderInfo() : "-";
        }
        else if( name.equals("interwikilinks") )
        {
            StringBuffer res = new StringBuffer();

            for( Iterator i = 
context.getEngine().getAllInterWikiLinks().iterator(); i.hasNext(); )
            {
                if( res.length() > 0 ) res.append(", ");
                String link = (String) i.next();
                res.append( link );
                res.append( " --> " );
                res.append( context.getEngine().getInterWikiURL(link) );    
            }
            return res.toString();
        }
        else if( name.equals("inlinedimages") )
        {
            StringBuffer res = new StringBuffer();

            for( Iterator i = 
context.getEngine().getAllInlinedImagePatterns().iterator(); i.hasNext(); )
            {
                if( res.length() > 0 ) res.append(", ");
                
                String ptrn = (String) i.next();
                res.append(ptrn);
            }
            
            return res.toString();
        }
        else if( name.equals("pluginpath") )
        {
            String s = context.getEngine().getPluginSearchPath();

            return (s == null) ? "-" : s;
        }
        else if( name.equals("baseurl") )
        {
            return context.getEngine().getBaseURL();
        }
        else if( name.equals("uptime") )
        {
            Date now = new Date();
            long secondsRunning = (now.getTime() - 
context.getEngine().getStartTime().getTime())/1000L;

            long seconds = secondsRunning % 60;
            long minutes = (secondsRunning /= 60) % 60;
            long hours   = (secondsRunning /= 60) % 24;
            long days    = secondsRunning /= 24;

            return days+"d, "+hours+"h "+minutes+"m "+seconds+"s";
        }
        else if( name.equals("loginstatus") )
        {
            WikiSession session = context.getWikiSession();
            return session.getStatus();
        }
        else if( name.equals("username") )
        {
            Principal wup = context.getCurrentUser();

            return wup != null ? wup.getName() : "not logged in";
        }
        else if( name.equals("requestcontext") )
        {
            return context.getRequestContext();
        }
        else if( name.equals("pagefilters") )
        {
            List filters = 
context.getEngine().getFilterManager().getFilterList();
            StringBuffer sb = new StringBuffer();

            for( Iterator i = filters.iterator(); i.hasNext(); )
            {
                PageFilter pf = (PageFilter)i.next();
                String f = pf.getClass().getName();

                if( pf instanceof InternalModule )
                    continue;

                if( sb.length() > 0 ) sb.append(", ");
                sb.append( f );
            }

            return sb.toString();
        }
        else
        {
            // 
            // Check if such a context variable exists,
            // returning its string representation.
            //
            if( (context.getVariable( varName )) != null )
            {
                return context.getVariable( varName ).toString();
            }

            //
            //  Well, I guess it wasn't a final straw.  We also allow 
            //  variables from the session and the request (in this order).
            //

            HttpServletRequest req = context.getHttpRequest();
            if( req != null && req.getSession() != null )
            {
                HttpSession session = req.getSession();

                try
                {
                    String s;
                    
                    if( (s = (String)session.getAttribute( varName )) != null )
                        return s;

                    if( (s = context.getHttpParameter( varName )) != null )
                        return s;
                }
                catch( ClassCastException e ) {}
            }

            // And the final straw: see if the current page has named metadata.
            
            WikiPage pg = context.getPage();
            if( pg != null )
            {
                Object metadata = pg.getAttribute( varName );
                if( metadata != null )
                    return metadata.toString();
            }
            
            // And the final straw part 2: see if the "real" current page has
            // named metadata. This allows a parent page to control a inserted
            // page through defining variables
            WikiPage rpg = context.getRealPage();
            if( rpg != null )
            {
                Object metadata = rpg.getAttribute( varName );
                if( metadata != null )
                    return metadata.toString();
            }
            
            // Next-to-final straw: attempt to fetch using property name
            // We don't allow fetching any other properties than those starting
            // with "jspwiki.".  I know my own code, but I can't vouch for bugs
            // in other people's code... :-)
            
            Properties props = context.getEngine().getWikiProperties();
            if( varName.startsWith("jspwiki.") )
            {

                String s = props.getProperty( varName );
                if( s != null )
                {
                    return s;
                }
            }
            // Our local preference: be able to define Aliases in properties to 
simplify long and repeated plugins!
            else if ((varName.length() > 1) && 
(varName.charAt(varName.length()-1) == '$')) {
                String s = props.getProperty( "alias."+varName.substring( 0, 
varName.length()-1 ));
                if( s != null )
                {
                    return makeHTML( context, s );
                }
               throw new NoSuchVariableException( "No alias 
"+varName.substring( 0, varName.length()-1 )+" defined in JSPWiki properties." 
);
            }
            
            //
            //  Final defaults for some known quantities.
            //

            if( varName.equals( VAR_ERROR ) || varName.equals( VAR_MSG ) )
                return "";
  
            throw new NoSuchVariableException( "No variable "+varName+" 
defined." );
        }
    }

}
/* 
  JSPWiki - a JSP-based WikiWiki clone.

  Copyright (C) 2001-2006 Janne Jalkanen ([EMAIL PROTECTED])

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published by
  the Free Software Foundation; either version 2.1 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package com.ecyrd.jspwiki.parser;

import org.apache.commons.lang.StringEscapeUtils;
import org.jdom.Text;

import java.io.IOException;

import com.ecyrd.jspwiki.NoSuchVariableException;
import com.ecyrd.jspwiki.WikiContext;
import com.ecyrd.jspwiki.render.RenderingManager;

/**
 *  Stores the contents of a WikiVariable in a WikiDocument DOM tree.
 *  @author Janne Jalkanen
 *  @since  2.4
 */
public class VariableContent extends Text
{
    private static final long serialVersionUID = 1L;

    private String m_varName;
    
    public VariableContent( String varName )
    {
        m_varName = varName;
    }
    
    /**
     *   Evaluates the variable and returns the contents.
     */
    public String getValue()
    {
        String result = "";
        WikiDocument root = (WikiDocument) getDocument();

        if( root == null )
        {
            // See similar note in PluginContent
            return m_varName;
        }
        
        WikiContext context = root.getContext();

        if( context == null )
            return "No WikiContext available: INTERNAL ERROR";
    
        Boolean wysiwygEditorMode = 
(Boolean)context.getVariable(RenderingManager.WYSIWYG_EDITOR_MODE);
        
        if( wysiwygEditorMode != null && wysiwygEditorMode.booleanValue() )
        {
            result = "[" + m_varName + "]";
        }
        else
        {
            try
            {
                result = 
context.getEngine().getVariableManager().parseAndGetValue( context, m_varName );
            }
            catch( IOException e )
            {
                result = JSPWikiMarkupParser.makeError("Alias "+m_varName+" has 
errors: "+e.getMessage()).getText(); 
            }
            catch( NoSuchVariableException e )
            {
                result = JSPWikiMarkupParser.makeError("No such variable: 
"+e.getMessage()).getText(); 
            }
        }

        
        return m_varName.endsWith("$}") ? result : StringEscapeUtils.escapeXml( 
result );
    }
    
    public String getText()
    {
        return getValue();
    }

    public String toString()
    {
        return "VariableElement[\""+m_varName+"\"]";
    }
}

Reply via email to