[jboss-cvs] jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui ...

Christian Bauer christian at hibernate.org
Thu Apr 5 09:04:14 EDT 2007


  User: cbauer  
  Date: 07/04/05 09:04:14

  Modified:    examples/wiki/src/main/org/jboss/seam/wiki/core/ui  
                        UIWikiFormattedText.java
  Added:       examples/wiki/src/main/org/jboss/seam/wiki/core/ui  
                        WikiFormattedTextComponentHandler.java
  Log:
  Fixed wiki plugin rendering of facelet includes by moving it into ComponentHandler
  
  Revision  Changes    Path
  1.13      +151 -186  jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: UIWikiFormattedText.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/UIWikiFormattedText.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -b -r1.12 -r1.13
  --- UIWikiFormattedText.java	2 Apr 2007 18:25:06 -0000	1.12
  +++ UIWikiFormattedText.java	5 Apr 2007 13:04:14 -0000	1.13
  @@ -1,12 +1,12 @@
   package org.jboss.seam.wiki.core.ui;
   
  -import java.net.URL;
   import java.util.*;
   import java.util.regex.Pattern;
   import java.util.regex.Matcher;
   import java.io.*;
   
   import javax.faces.component.UIOutput;
  +import javax.faces.component.UIComponent;
   import javax.faces.context.FacesContext;
   import javax.faces.context.ResponseWriter;
   
  @@ -17,54 +17,51 @@
   import org.jboss.seam.wiki.core.engine.WikiLink;
   import org.jboss.seam.wiki.core.engine.WikiTextRenderer;
   import org.jboss.seam.wiki.core.engine.WikiTextParser;
  -import org.jboss.seam.wiki.core.action.PluginPreferenceEditor;
   import org.jboss.seam.wiki.core.action.prefs.WikiPreferences;
   import org.jboss.seam.wiki.util.WikiUtil;
   import org.jboss.seam.Component;
   import org.jboss.seam.core.Expressions;
   import org.jboss.seam.core.Conversation;
   
  -import com.sun.facelets.Facelet;
  -import com.sun.facelets.impl.DefaultFaceletFactory;
  -import com.sun.facelets.impl.DefaultResourceResolver;
  -import com.sun.facelets.compiler.SAXCompiler;
  +public class UIWikiFormattedText extends UIOutput {
   
  -public class UIWikiFormattedText extends UIOutput implements WikiTextRenderer {
  +    public static final String COMPONENT_FAMILY = "org.jboss.seam.wiki.core.ui.UIWikiFormattedText";
  +    public static final String COMPONENT_TYPE = "org.jboss.seam.wiki.core.ui.UIWikiFormattedText";
   
  -    public static final String COMPONENT_FAMILY = "org.jboss.seam.wiki.core.ui.WikiFormattedText";
  -
  -    private Set<String> includedViews = new HashSet<String>();
  +    public UIWikiFormattedText() {
  +        super();
  +        setRendererType(null);
  +    }
   
  -    @Override
       public String getFamily() {
           return COMPONENT_FAMILY;
       }
   
  -    @Override
       public boolean getRendersChildren() {
          return true;
       }
   
  -    @Override
  +    public void encodeChildren(FacesContext facesContext) throws IOException {
  +        // Already done by WikiTextRenderer
  +    }
  +
       public void encodeBegin(FacesContext facesContext) throws IOException {
           if (!isRendered() || getValue() == null) return;
   
  -        // Use the WikiTextParser to resolve links
  -        WikiTextParser parser = new WikiTextParser((String)getValue(), this);
  -        parser.parse(true);
  -
  -        facesContext.getResponseWriter().write(parser.toString());
  -    }
  +        // Use the WikiTextParser to resolve macros
  +        WikiTextParser parser = new WikiTextParser((String)getValue(), false);
   
  -    public void encodeChildren(FacesContext facesContext) throws IOException {
  -        // Already done
  -    }
  +        // Set a customized renderer for parser macro callbacks
  +        parser.setRenderer(
  +            new WikiTextRenderer() {
   
       public String renderInlineLink(WikiLink inlineLink) {
           return "<a href=\""
                   + (inlineLink.isBroken() ? inlineLink.getUrl() : WikiUtil.renderURL(inlineLink.getNode()))
                   + "\" class=\""
  -                + (inlineLink.isBroken() ? getAttributes().get("brokenLinkStyleClass") : getAttributes().get("linkStyleClass"))
  +                            + (inlineLink.isBroken()
  +                                ? getAttributes().get("brokenLinkStyleClass")
  +                                : getAttributes().get("linkStyleClass"))
                   + "\">"
                   + inlineLink.getDescription()
                   + "</a>";
  @@ -74,7 +71,9 @@
           return "<a href=\""
                   + externalLink.getUrl()
                   + "\" class=\""
  -                + (externalLink.isBroken() ? getAttributes().get("brokenLinkStyleClass") : getAttributes().get("linkStyleClass"))
  +                            + (externalLink.isBroken()
  +                                ? getAttributes().get("brokenLinkStyleClass")
  +                                : getAttributes().get("linkStyleClass"))
                   + "\">"
                   + externalLink.getDescription()
                   + "</a>";
  @@ -101,7 +100,7 @@
               case 'L': thumbnailWidth = 320; break;
               default: thumbnailWidth = file.getImageMetaInfo().getSizeX();
           }
  -        Conversation conversation = (Conversation)Component.getInstance("conversation");
  +                    Conversation conversation = (Conversation) Component.getInstance("conversation");
           String thumbnailUrl = WikiUtil.renderURL(inlineLink.getNode()) + "&width=" + thumbnailWidth + "&cid=" + conversation.getId();
   
           return "<a href=\""
  @@ -113,63 +112,18 @@
                   + "\"/></a>";
       }
   
  -    public void setAttachmentLinks(List<WikiLink> attachmentLinks) {
  -        // Put attachments (wiki links...) into the event context for later rendering
  -        Contexts.getEventContext().set("wikiTextAttachments", attachmentLinks);
  -    }
  -
  -    public void setExternalLinks(List<WikiLink> externalLinks) {
  -        // Put external links (to targets not on this wiki) into the event context for later rendering
  -        Contexts.getEventContext().set("wikiTextExternalLinks", externalLinks);
  -    }
  -
  -    public void setMacroNames(Set<String> macroNames) {
  -        // Put macro names into the event context for later usage
  -        Contexts.getEventContext().set("wikiTextMacroNames", macroNames);
  -    }
  -
       public String renderMacro(String macroName) {
           if (macroName == null || macroName.length() == 0) return "";
   
  -        String includeView = "/plugins/" + macroName + "/plugin.xhtml";
  -
  -        // TODO: Can only include once (otherwise we'd have to renumber child identifiers recursively...)
  -        if (includedViews.contains(includeView)) return "[Can't use the same plugin twice!]";
  -
  -        // View can't include itself
  -        FacesContext facesContext = getFacesContext();
  -        if (facesContext.getViewRoot().getViewId().equals(includeView)) return "";
  -
  -        // Try to get the XHTML document
  -        URL url = Resources.getResource(includeView);
  -        if (url == null) return "";
  -
           // Try to get the CSS for it
           WikiPreferences wikiPrefs = (WikiPreferences) Component.getInstance("wikiPreferences");
           String includeViewCSS = "/themes/" + wikiPrefs.getThemeName() + "/css/" + macroName + ".css";
   
  -        // If this plugin has preferences and editing is enabled, instantiate a
  -        // plugin preferences editor and put it in the PAGE context 
  -        String pluginPreferenceName = macroName + "Preferences";
  -        Boolean showPluginPreferences = (Boolean)Component.getInstance("showPluginPreferences");
  -        Object existingEditor = Contexts.getConversationContext().get(pluginPreferenceName+"Editor");
  -        if ( showPluginPreferences != null && showPluginPreferences && existingEditor == null) {
  -            PluginPreferenceEditor pluginPreferenceEditor = new PluginPreferenceEditor(pluginPreferenceName);
  -            PluginPreferenceEditor.FlushObserver observer =
  -                    (PluginPreferenceEditor.FlushObserver)Component.getInstance("pluginPreferenceEditorFlushObserver");
  -            if (pluginPreferenceEditor.getPreferenceValues().size() > 0) {
  -                Contexts.getConversationContext().set(pluginPreferenceName+"Editor", pluginPreferenceEditor);
  -                observer.addPluginPreferenceEditor(pluginPreferenceEditor);
  -            }
  -        } else if (showPluginPreferences == null || !showPluginPreferences) {
  -            Contexts.getConversationContext().set(pluginPreferenceName+"Editor", null);
  -        }
  -
           // Prepare all the writers for rendering
  -        ResponseWriter originalResponseWriter = facesContext.getResponseWriter();
  +                    ResponseWriter originalResponseWriter = getFacesContext().getResponseWriter();
           StringWriter stringWriter = new StringWriter();
           ResponseWriter tempResponseWriter = originalResponseWriter.cloneWithWriter(stringWriter);
  -        facesContext.setResponseWriter(tempResponseWriter);
  +                    getFacesContext().setResponseWriter(tempResponseWriter);
   
           StringBuilder output = new StringBuilder();
   
  @@ -182,7 +136,7 @@
                   BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                   StringBuilder css = new StringBuilder();
                   String line;
  -                while ( (line = reader.readLine()) != null) {
  +                            while ((line = reader.readLine()) != null) {
                       css.append(line);
                       css.append("\n");
                   }
  @@ -192,13 +146,13 @@
                   StringBuffer resolvedCSS = new StringBuffer(css.length());
                   Matcher matcher =
                       Pattern.compile(
  -                        "#" +Pattern.quote("{") + "(.*)" + Pattern.quote("}")
  +                                            "#" + Pattern.quote("{") + "(.*)" + Pattern.quote("}")
                       ).matcher(css);
   
                   // Replace with [Link Text=>Page Name] or replace with BROKENLINK "page name"
                   while (matcher.find()) {
  -                    Expressions.ValueBinding valueMethod = Expressions.instance().createValueBinding("#{"+matcher.group(1)+"}");
  -                    String result = (String)valueMethod.getValue();
  +                                Expressions.ValueBinding valueMethod = Expressions.instance().createValueBinding("#{" + matcher.group(1) + "}");
  +                                String result = (String) valueMethod.getValue();
                       if (result != null) {
                           matcher.appendReplacement(resolvedCSS, result);
                       } else {
  @@ -211,29 +165,40 @@
                   output.append("</style>\n");
               }
   
  -            // Render XHTML
  -            Facelet f = new DefaultFaceletFactory(new SAXCompiler(), new DefaultResourceResolver()).getFacelet(url);
  -
  -            // TODO: I'm not sure this is good...
  -            List storedChildren = new ArrayList(getChildren());
  -            getChildren().clear();
  -
  -            // TODO: This is why I copy the list back and forth: apply() hammers the children
  -            f.apply(facesContext, this);
  -            JSF.renderChildren(facesContext, this);
  -
  -            // TODO: And back... it's definitely in the wrong order in the component tree but the ids look ok to me...
  -            getChildren().addAll(storedChildren);
  +                        // Render the actual child component - the plugin XHTML
  +                        UIComponent pluginChild = findComponent(macroName);
  +                        if (pluginChild == null) throw new RuntimeException("Couldn't find plugin child component: " + macroName);
  +                        pluginChild.encodeBegin(getFacesContext());
  +                        JSF.renderChildren(getFacesContext(), pluginChild);
  +                        pluginChild.encodeEnd(getFacesContext());
   
               output.append(stringWriter.getBuffer().toString());
   
           } catch (Exception ex) {
               throw new RuntimeException(ex);
           } finally {
  -            includedViews.add(includeView);
  -            facesContext.setResponseWriter(originalResponseWriter);
  +                        getFacesContext().setResponseWriter(originalResponseWriter);
           }
           return output.toString();
       }
   
  +                public void setAttachmentLinks(List<WikiLink> attachmentLinks) {
  +                    // Put attachments (wiki links...) into the event context for later rendering
  +                    Contexts.getEventContext().set("wikiTextAttachments", attachmentLinks);
  +                }
  +
  +                public void setExternalLinks(List<WikiLink> externalLinks) {
  +                    // Put external links (to targets not on this wiki) into the event context for later rendering
  +                    Contexts.getEventContext().set("wikiTextExternalLinks", externalLinks);
  +                }
  +            }
  +        );
  +
  +        // Run the parser
  +        parser.parse(true);
  +
  +        facesContext.getResponseWriter().write( parser.toString() );
  +
  +    }
  +    
   }
  
  
  
  1.1      date: 2007/04/05 13:04:14;  author: cbauer;  state: Exp;jboss-seam/examples/wiki/src/main/org/jboss/seam/wiki/core/ui/WikiFormattedTextComponentHandler.java
  
  Index: WikiFormattedTextComponentHandler.java
  ===================================================================
  package org.jboss.seam.wiki.core.ui;
  
  import com.sun.facelets.tag.jsf.ComponentHandler;
  import com.sun.facelets.tag.jsf.ComponentConfig;
  import com.sun.facelets.FaceletContext;
  
  import javax.faces.component.UIComponent;
  
  import org.jboss.seam.wiki.core.action.PluginPreferenceEditor;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.Component;
  import org.jboss.seam.util.Resources;
  
  import java.util.*;
  import java.util.regex.Pattern;
  import java.util.regex.Matcher;
  import java.net.URL;
  
  /**
   * Includes plugin facelets at the right time, when the component tree is build by Facelets.
   *
   * @author Christian Bauer
   */
  public class WikiFormattedTextComponentHandler extends ComponentHandler {
  
      public static final String REGEX_MACRO = Pattern.quote("[") + "<=([a-zA-Z0-9]+)" + Pattern.quote("]");
  
      public WikiFormattedTextComponentHandler(ComponentConfig componentConfig) {
          super(componentConfig);
      }
  
      protected void onComponentPopulated(FaceletContext faceletContext, UIComponent c, UIComponent parent) {
          UIWikiFormattedText component = (UIWikiFormattedText)c;
  
          if (component.getValue() == null) return;
  
          Set<String> includedMacros = new HashSet<String>();
          Matcher matcher = Pattern.compile(REGEX_MACRO).matcher((String)component.getValue());
          while (matcher.find()) {
              String macroName = matcher.group(1);
  
              if (includedMacros.contains(macroName)) continue;
  
              String includeView = "/plugins/" + macroName + "/plugin.xhtml";
  
              // View can't include itself
              String currentViewId = faceletContext.getFacesContext().getViewRoot().getViewId();
              if (currentViewId.equals(includeView)) continue;
  
              // Try to get the XHTML document
              URL includeViewURL = Resources.getResource(includeView);
              if (includeViewURL == null) continue;
  
              try {
                  // Include plugin Facelet as a child
                  faceletContext.includeFacelet(component, includeViewURL);
              } catch (Exception ex) {
                  throw new RuntimeException(ex);
              } finally {
                  includedMacros.add(macroName);
              }
  
              // If this plugin has preferences and editing is enabled, instantiate a
              // plugin preferences editor and put it in the PAGE context
              String pluginPreferenceName = macroName + "Preferences";
              Boolean showPluginPreferences = (Boolean)Component.getInstance("showPluginPreferences");
              Object existingEditor = Contexts.getConversationContext().get(pluginPreferenceName+"Editor");
              if ( showPluginPreferences != null && showPluginPreferences && existingEditor == null) {
                  PluginPreferenceEditor pluginPreferenceEditor = new PluginPreferenceEditor(pluginPreferenceName);
                  PluginPreferenceEditor.FlushObserver observer =
                          (PluginPreferenceEditor.FlushObserver)Component.getInstance("pluginPreferenceEditorFlushObserver");
                  if (pluginPreferenceEditor.getPreferenceValues().size() > 0) {
                      Contexts.getConversationContext().set(pluginPreferenceName+"Editor", pluginPreferenceEditor);
                      observer.addPluginPreferenceEditor(pluginPreferenceEditor);
                  }
              } else if (showPluginPreferences == null || !showPluginPreferences) {
                  Contexts.getConversationContext().set(pluginPreferenceName+"Editor", null);
              }
  
          }
      }
  
  }
  
  
  



More information about the jboss-cvs-commits mailing list