All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.facelets.compiler.JsfelcheckCompilationManager Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sun.facelets.compiler;

import com.sun.facelets.FaceletHandler;
import com.sun.facelets.tag.Tag;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagAttributeException;
import com.sun.facelets.tag.TagAttributes;
import com.sun.facelets.tag.TagDecorator;
import com.sun.facelets.tag.TagException;
import com.sun.facelets.tag.TagLibrary;
import com.sun.facelets.tag.ui.ComponentRefHandler;
import com.sun.facelets.tag.ui.CompositionHandler;
import com.sun.facelets.tag.ui.UILibrary;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Copy of MyFaces CompilationManager with slight adjustments, from MyFaces v1.2.10.
 * 
 * The difference is that I made it non-final and abstract and increased the visibility of
 * currentUnit() and determineQName(..) to protected.
 *
 * 

* Notice we must be in the myfaces package to be able to see package-private classes that the * compiler and c. manager use. *

* * @version Id: CompilationManager.java,v 1.15 2008/07/13 19:01:34 rlubke Exp */ abstract class JsfelcheckCompilationManager { private final static Logger log = Logger.getLogger("facelets.compiler"); private final Compiler compiler; private final TagLibrary tagLibrary; private final TagDecorator tagDecorator; private final NamespaceManager namespaceManager; private final Stack units; private int tagId; private boolean finished; private final String alias; public JsfelcheckCompilationManager(String alias, Compiler compiler) { // this is our alias this.alias = alias; // grab compiler state this.compiler = compiler; this.tagDecorator = compiler.createTagDecorator(); this.tagLibrary = compiler.createTagLibrary(); // namespace management this.namespaceManager = new NamespaceManager(); // tag uids this.tagId = 0; // for composition use this.finished = false; // our compilationunit stack this.units = new Stack(); this.units.push(new CompilationUnit()); } public void writeInstruction(String value) { if (this.finished) { return; } // don't carelessly add empty tags if (value.length() == 0) { return; } TextUnit unit; if (this.currentUnit() instanceof TextUnit) { unit = (TextUnit) this.currentUnit(); } else { unit = new TextUnit(this.alias, this.nextTagId()); this.startUnit(unit); } unit.writeInstruction(value); } public void writeText(String value) { if (this.finished) { return; } // don't carelessly add empty tags if (value.length() == 0) { return; } TextUnit unit; if (this.currentUnit() instanceof TextUnit) { unit = (TextUnit) this.currentUnit(); } else { unit = new TextUnit(this.alias, this.nextTagId()); this.startUnit(unit); } unit.write(value); } public void writeComment(String text) { if (this.compiler.isTrimmingComments()) return; if (this.finished) { return; } // don't carelessly add empty tags if (text.length() == 0) { return; } TextUnit unit; if (this.currentUnit() instanceof TextUnit) { unit = (TextUnit) this.currentUnit(); } else { unit = new TextUnit(this.alias, this.nextTagId()); this.startUnit(unit); } unit.writeComment(text); } public void writeWhitespace(String text) { if (!this.compiler.isTrimmingWhitespace()) { this.writeText(text); } } private String nextTagId() { return Integer.toHexString(Math.abs(this.alias.hashCode() ^ 13 * this.tagId++)); } public void pushTag(Tag orig) { if (this.finished) { return; } if (log.isLoggable(Level.FINE)) { log.fine("Tag Pushed: " + orig); } Tag t = this.tagDecorator.decorate(orig); String[] qname = this.determineQName(t); t = this.trimAttributes(t); boolean handled = false; if (isTrimmed(qname[0], qname[1])) { log.fine("Composition Found, Popping Parent Tags"); this.units.clear(); NamespaceUnit nsUnit = this.namespaceManager .toNamespaceUnit(this.tagLibrary); this.units.push(nsUnit); this.startUnit(new TrimmedTagUnit(this.tagLibrary, qname[0], qname[1], t, this .nextTagId())); log.fine("New Namespace and [Trimmed] TagUnit pushed"); } else if (isRemove(qname[0], qname[1])) { this.units.push(new RemoveUnit()); } else if (this.tagLibrary.containsTagHandler(qname[0], qname[1])) { this.startUnit(new TagUnit(this.tagLibrary, qname[0], qname[1], t, this.nextTagId())); } else if (this.tagLibrary.containsNamespace(qname[0])) { throw new TagException(orig, "Tag Library supports namespace: "+qname[0]+", but no tag was defined for name: "+qname[1]); } else { TextUnit unit; if (this.currentUnit() instanceof TextUnit) { unit = (TextUnit) this.currentUnit(); } else { unit = new TextUnit(this.alias, this.nextTagId()); this.startUnit(unit); } unit.startTag(t); } } public void popTag() { if (this.finished) { return; } CompilationUnit unit = this.currentUnit(); if (unit instanceof TextUnit) { TextUnit t = (TextUnit) unit; if (t.isClosed()) { this.finishUnit(); } else { t.endTag(); return; } } unit = this.currentUnit(); if (unit instanceof TagUnit) { TagUnit t = (TagUnit) unit; if (t instanceof TrimmedTagUnit) { this.finished = true; return; } } this.finishUnit(); } public void popNamespace(String ns) { this.namespaceManager.popNamespace(ns); if (this.currentUnit() instanceof NamespaceUnit) { this.finishUnit(); } } public void pushNamespace(String prefix, String uri) { if (log.isLoggable(Level.FINE)) { log.fine("Namespace Pushed " + prefix + ": " + uri); } this.namespaceManager.pushNamespace(prefix, uri); NamespaceUnit unit; if (this.currentUnit() instanceof NamespaceUnit) { unit = (NamespaceUnit) this.currentUnit(); } else { unit = new NamespaceUnit(this.tagLibrary); this.startUnit(unit); } unit.setNamespace(prefix, uri); } public FaceletHandler createFaceletHandler() { return ((CompilationUnit) this.units.get(0)).createFaceletHandler(); } protected final CompilationUnit currentUnit() { if (!this.units.isEmpty()) { return (CompilationUnit) this.units.peek(); } return null; } private void finishUnit() { Object obj = this.units.pop(); if (log.isLoggable(Level.FINE)) { log.fine("Finished Unit: " + obj); } } private CompilationUnit searchUnits(Class type) { CompilationUnit unit = null; int i = this.units.size(); while (unit == null && --i >= 0) { if (type.isAssignableFrom(this.units.get(i).getClass())) { unit = (CompilationUnit) this.units.get(i); } } return unit; } private void startUnit(CompilationUnit unit) { if (log.isLoggable(Level.FINE)) { log.fine("Starting Unit: " + unit + " and adding it to parent: " + this.currentUnit()); } this.currentUnit().addChild(unit); this.units.push(unit); } private Tag trimAttributes(Tag tag) { Tag t = this.trimJSFCAttribute(tag); t = this.trimNSAttributes(t); return t; } protected static boolean isRemove(String ns, String name) { return UILibrary.Namespace.equals(ns) && "remove".equals(name); } protected static boolean isTrimmed(String ns, String name) { return UILibrary.Namespace.equals(ns) && (CompositionHandler.Name.equals(name) || ComponentRefHandler.Name.equals(name)); } protected final String[] determineQName(Tag tag) { TagAttribute attr = tag.getAttributes().get("jsfc"); if (attr != null) { if (log.isLoggable(Level.FINE)) { log.fine(attr + " JSF Facelet Compile Directive Found"); } String value = attr.getValue(); String namespace, localName; int c = value.indexOf(':'); if (c == -1) { namespace = this.namespaceManager.getNamespace(""); localName = value; } else { String prefix = value.substring(0, c); namespace = this.namespaceManager.getNamespace(prefix); if (namespace == null) { throw new TagAttributeException(tag, attr, "No Namespace matched for: " + prefix); } localName = value.substring(c + 1); } return new String[] { namespace, localName }; } else { return new String[] { tag.getNamespace(), tag.getLocalName() }; } } private Tag trimJSFCAttribute(Tag tag) { TagAttribute attr = tag.getAttributes().get("jsfc"); if (attr != null) { TagAttribute[] oa = tag.getAttributes().getAll(); TagAttribute[] na = new TagAttribute[oa.length - 1]; int p = 0; for (int i = 0; i < oa.length; i++) { if (!"jsfc".equals(oa[i].getLocalName())) { na[p++] = oa[i]; } } return new Tag(tag, new TagAttributes(na)); } return tag; } private Tag trimNSAttributes(Tag tag) { TagAttribute[] attr = tag.getAttributes().getAll(); int remove = 0; for (int i = 0; i < attr.length; i++) { if (attr[i].getQName().startsWith("xmlns") && this.tagLibrary.containsNamespace(attr[i].getValue())) { remove |= 1 << i; if (log.isLoggable(Level.FINE)) { log.fine(attr[i] + " Namespace Bound to TagLibrary"); } } } if (remove == 0) { return tag; } else { List attrList = new ArrayList(attr.length); int p = 0; for (int i = 0; i < attr.length; i++) { p = 1 << i; if ((p & remove) == p) { continue; } attrList.add(attr[i]); } attr = (TagAttribute[]) attrList.toArray(new TagAttribute[attrList .size()]); return new Tag(tag.getLocation(), tag.getNamespace(), tag .getLocalName(), tag.getQName(), new TagAttributes(attr)); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy