Author: pier Date: Sun Oct 31 19:12:48 2004 New Revision: 56188 Added: cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Abstract.java Modified: cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Block.java cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Descriptor.java cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/runtime/Instance.java Log: Separating extendibilty and provisions to achieve full multiple inheritance of blocks
Added: cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Abstract.java ============================================================================== --- (empty file) +++ cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Abstract.java Sun Oct 31 19:12:48 2004 @@ -0,0 +1,77 @@ +/* =============================================================================== * + * Copyright (C) 1999-2004, The Apache Software Foundation. All rights reserved. * + * * + * Licensed 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 org.apache.cocoon.kernel.description; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.cocoon.kernel.KernelException; +import org.apache.cocoon.kernel.configuration.Configuration; + +/** + * <p>An [EMAIL PROTECTED] Abstract} represents a an descriptor, or a block providing only + * libraries, but no usable components.</p> + * + * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> + * @author Copyright © 2000-2004 <a href="http://www.apache.org/">The Apache + * Software Foundation</a>. All rights reserved. + */ +public class Abstract extends Descriptor { + + /** <p>The array of identifiers of all extended blocks.</p> */ + private String[] extensions = null; + + /** + * <p>Create a new [EMAIL PROTECTED] Abstract} instance.</p> + */ + public Abstract(Configuration configuration) + throws KernelException { + super(configuration); + + /* Specific block stuff */ + String name = configuration.name(); + if ((!"block".equals(name)) && (!"abstract".equals(name))) { + throw new KernelException("Invalid root element name for abstract " + + " descriptor at " + configuration.location()); + } + + /* Extensions */ + Iterator iterator = configuration.children(NAMESPACE, "extends"); + Set list = new HashSet(); + while (iterator.hasNext()) { + Configuration current = (Configuration) iterator.next(); + String id = current.getStringAttribute("block", null); + if (id == null) { + throw new KernelException("Extended block identifier not speci" + + "fied in descriptor at " + configuration.location()); + } + list.add(id); + } + this.extensions = (String[]) list.toArray(new String[list.size()]); + } + + /** + * <p>Return the type of this descriptor.</p> + */ + public int getType() { + return Descriptor.ABSTRACT; + } + + /** + * <p>Return an array of all extended block identifers.</p> + */ + public String[] getExtendedBlocks() { + return(this.extensions); + } +} Modified: cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Block.java ============================================================================== --- cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Block.java (original) +++ cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Block.java Sun Oct 31 19:12:48 2004 @@ -20,13 +20,13 @@ import org.apache.cocoon.kernel.configuration.Configuration; /** - * <p>An [EMAIL PROTECTED] Block} represents an block descriptor.</p> + * <p>A [EMAIL PROTECTED] Block} represents a block descriptor.</p> * * @author <a href="mailto:[EMAIL PROTECTED]">Pier Fumagalli</a> * @author Copyright © 2000-2004 <a href="http://www.apache.org/">The Apache * Software Foundation</a>. All rights reserved. */ -public class Block extends Descriptor { +public class Block extends Abstract { /** <p>The name of the exposed Java interface.</p> */ private String clazz = null; @@ -36,8 +36,6 @@ private String destroyer = null; /** <p>Whether the component is a singleton or not.</p> */ private boolean singleton = true; - /** <p>The array of identifiers of all extended blocks.</p> */ - private String[] extensions = null; /** <p>The array of identifiers of all implemented interfaces.</p> */ private String[] implementations = null; @@ -52,19 +50,34 @@ /* Parse all generic stuff */ super(configuration); - /* Specific interface stuff */ + /* Specific block stuff */ if (! "block".equals(configuration.name())) { - throw new KernelException("Invalid root element name for interface " + throw new KernelException("Invalid root element name for block " + " descriptor at " + configuration.location()); } + /* Implementations */ + Iterator iterator = configuration.children(NAMESPACE, "extends"); + Set list = new HashSet(); + while (iterator.hasNext()) { + Configuration current = (Configuration) iterator.next(); + String id = current.getStringAttribute("block", null); + if (id == null) { + throw new KernelException("Extended block identifier not speci" + + "fied in descriptor at " + configuration.location()); + } + list.add(id); + } + this.implementations = (String[]) list.toArray(new String[list.size()]); + /* Provision */ Configuration provides = configuration.child(NAMESPACE, "provides"); this.clazz = provides.getStringAttribute("component", null); - if (this.clazz == null) { - throw new KernelException("Provided class name not specified at " - + provides.location()); - } + + /* No class? Abstract block, only libraries */ + if (this.clazz == null) return; + + /* Process initializer, destroyer, and singleton */ this.initializer = provides.getStringAttribute("initialize", null); this.destroyer = provides.getStringAttribute("destroy", null); this.singleton = provides.getBooleanAttribute("singleton", true); @@ -73,37 +86,13 @@ + "or destroyer method at " + provides.location()); } - /* Extensions and implementations */ - Iterator iterator = null; - Set list = null; - - /* Extensions */ - iterator = configuration.children(NAMESPACE, "extends"); - list = new HashSet(); - while (iterator.hasNext()) { - Configuration current = (Configuration) iterator.next(); - String id = current.getStringAttribute("block", null); - if (id == null) { - throw new KernelException("Extended block identifier not speci" - + "fied in descriptor at " + configuration.location()); - } - list.add(id); - } - this.extensions = (String[]) list.toArray(new String[list.size()]); + } - /* Implementations */ - iterator = configuration.children(NAMESPACE, "extends"); - list = new HashSet(); - while (iterator.hasNext()) { - Configuration current = (Configuration) iterator.next(); - String id = current.getStringAttribute("block", null); - if (id == null) { - throw new KernelException("Extended block identifier not speci" - + "fied in descriptor at " + configuration.location()); - } - list.add(id); - } - this.implementations = (String[]) list.toArray(new String[list.size()]); + /** + * <p>Check if this block is an <i>abstract</i> block.</p> + */ + public boolean isAbstract() { + return(this.clazz == null); } /** @@ -132,13 +121,6 @@ */ public boolean isSingletonComponent() { return(this.singleton); - } - - /** - * <p>Return an array of all extended block identifers.</p> - */ - public String[] getExtendedBlocks() { - return(this.extensions); } /** Modified: cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Descriptor.java ============================================================================== --- cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Descriptor.java (original) +++ cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/description/Descriptor.java Sun Oct 31 19:12:48 2004 @@ -33,6 +33,8 @@ /** <p>The namespace declaration of the XML descriptor.</p> */ public static final String NAMESPACE = "http://apache.org/cocoon/blocks/descriptor/1.0"; + /** <p>The type identifying an abstract descriptor.</p> */ + public static final int ABSTRACT = 0; /** <p>The type identifying a block descriptor.</p> */ public static final int BLOCK = 1; /** <p>The type identifying an interface descriptor.</p> */ Modified: cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/runtime/Instance.java ============================================================================== --- cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/runtime/Instance.java (original) +++ cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/runtime/Instance.java Sun Oct 31 19:12:48 2004 @@ -19,6 +19,7 @@ import java.util.Set; import org.apache.cocoon.kernel.KernelException; +import org.apache.cocoon.kernel.description.Abstract; import org.apache.cocoon.kernel.description.Block; import org.apache.cocoon.kernel.description.Descriptor; import org.apache.cocoon.kernel.description.Interface; @@ -61,7 +62,7 @@ throw new KernelException("Block " + block.toString() + " implements unknown block " + implementations[k]); } - if (descriptor.getType() != Descriptor.BLOCK) { + if (descriptor.getType() != Descriptor.INTERFACE) { throw new KernelException("Block " + block.toString() + " implements non-interface " + descriptor.toString()); } @@ -85,12 +86,12 @@ throw new KernelException("Block " + block.toString() + " extends unknown block " + extensions[k]); } - if (descriptor.getType() != Descriptor.BLOCK) { + if (descriptor.getType() == Descriptor.INTERFACE) { throw new KernelException("Block " + block.toString() - + " extends non-block " + descriptor.toString()); + + " extends interface " + descriptor.toString()); } collector.add(block); - this.process(library, (Block) descriptor, collector, interfaces); + this.process(library, (Abstract) descriptor, collector, interfaces); } /* Resolve the component class and verify that it implements what it must */ @@ -167,51 +168,53 @@ /** * <p>Add all libraries provided by a given block and its super-blocks.</p> */ - private void process(Library library, Block block, Set collector, Set interfaces) + private void process(Library lib, Abstract abs, Set collector, Set interfaces) throws KernelException { /* Check circularities */ - if (collector.contains(block)) { + if (collector.contains(abs)) { throw new KernelException("Circularity exception analysing " - + "extensions for block " + block.toString()); + + "extensions for block " + abs.toString()); } - collector.add(block); + collector.add(abs); /* Process interfaces */ - String implementations[] = block.getImplementedInterfaces(); - for (int k = 0; k < implementations.length; k++) { - Descriptor descriptor = library.get(implementations[k]); - if (descriptor == null) { - throw new KernelException("Block " + block.toString() - + " implements unknown block " + implementations[k]); - } - if (descriptor.getType() != Descriptor.BLOCK) { - throw new KernelException("Block " + block.toString() - + " implements non-interface " + descriptor.toString()); - } - - String clazz = ((Interface) descriptor).getInterface(); - try { - interfaces.add(this.getParent().loadClass(clazz)); - } catch (ClassNotFoundException e) { - throw new KernelException("Cant find class " + clazz + " exposed by " - + "interface " + descriptor.toString() + " implemented by " - + block.toString()); + if (abs.getType() == Descriptor.BLOCK) { + String implementations[] = ((Block)abs).getImplementedInterfaces(); + for (int k = 0; k < implementations.length; k++) { + Descriptor descriptor = lib.get(implementations[k]); + if (descriptor == null) { + throw new KernelException("Block " + abs.toString() + " imple" + + "ments unknown interface " + implementations[k]); + } + if (descriptor.getType() != Descriptor.INTERFACE) { + throw new KernelException("Block " + abs.toString() + + " implements non-interface " + descriptor.toString()); + } + + String clazz = ((Interface) descriptor).getInterface(); + try { + interfaces.add(this.getParent().loadClass(clazz)); + } catch (ClassNotFoundException e) { + throw new KernelException("Cant find class " + clazz + + " exposed by interface " + descriptor.toString() + + " implemented by " + abs.toString()); + } } } /* Process libraries */ - URL libraries[] = block.getLibraries(); + URL libraries[] = abs.getLibraries(); for (int k = 0; k < libraries.length; k++) { super.addURL(libraries[k]); } - String extensions[] = block.getExtendedBlocks(); + String extensions[] = abs.getExtendedBlocks(); for (int k = 0; k < extensions.length; k++) { - Descriptor descriptor = library.get(extensions[k]); - if (descriptor.getType() != Descriptor.BLOCK) { - throw new KernelException("Block " + block.toString() - + " extends non-block " + descriptor.toString()); + Descriptor descriptor = lib.get(extensions[k]); + if (descriptor.getType() == Descriptor.INTERFACE) { + throw new KernelException("Block " + abs.toString() + + " extends interface " + descriptor.toString()); } - this.process(library, (Block) descriptor, collector, interfaces); + this.process(lib, (Block) descriptor, collector, interfaces); } } }