Return-Path: Mailing-List: contact cocoon-dev-help@xml.apache.org; run by ezmlm Delivered-To: mailing list cocoon-dev@xml.apache.org Received: (qmail 75592 invoked from network); 13 Jan 2000 03:11:54 -0000 Received: from dfwns08.algx.net (216.99.225.37) by 63.211.145.10 with SMTP; 13 Jan 2000 03:11:54 -0000 Received: from algx.net ([216.99.228.84]) by dfwns08.algx.net (Post.Office MTA v3.5.2 release 221 ID# 0-56809U5000L5300S0V35) with ESMTP id net for ; Wed, 12 Jan 2000 21:09:33 -0600 Message-ID: <387D426C.BDA6CA4@algx.net> Date: Wed, 12 Jan 2000 21:11:40 -0600 From: Brett McLaughlin X-Mailer: Mozilla 4.7 [en] (WinNT; I) X-Accept-Language: en MIME-Version: 1.0 To: cocoon-dev@xml.apache.org Subject: [Proposal] Shared Objects & Services Architecture Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Disclaimer: Much of the following proposal is tangential to Cocoon. However, because it, similar to Avalon, is ahead of its time, the list here would seem to be the most logical and receptive group for feedback and input. Problem: Applications today are too tightly coupled. As application assemblers combine useful components, these components become dependent on the specific framework they are used within. In effect, for components A, B, and C, and framework D, the combination becomes a new unit, which we will call an application. This application is completely proprietary, as is appropriate for any given application. However, in the process, components A, B, and C become proprietary as well. This means an upgrade to any of these components causes changed in the framework D, and possible other components. In addition, any component E with the same methods as component A should be interchangeable at an implementation level. In the situation outlined here, common in many companies and organizaions, this exchange of components is impossible. Goal: To design an interface layer, which in turn implements design patters from Avalon (re: newest versions, including modifications in James), that provide a loosely coupled architecture for using components, particularly in regards to the Java Apache and XML Apache efforts. This model should be applicable, but not limited, to Apache Tomcat, Apache Cocoon, Apache Turbine, and the EJB Server being developed at Exolabs. In addition, this same model should provide mechanisms for using common Java services, such as JDBC connection pooling, JNDI context management, XML-RPC, and other tasks that span more than a specific component. Requirements & Assumptions: (1) Components in isolation are not necessarily useful. While Cocoon serves as a standalone offering, JDBC connection pooling certainly does not. (2) An application developed by an application assembler or developer will be critical for the combining of components into a business purpose. (3) These application control structures must not be forced to conform to an API. For example, a servlet control is not appropriate as it removes the ability for a component or framework to generate filtering and piping of the output. This closely adheres to the Producer design pattern in Cocoon today. (4) Generality should be strived for over specificity. In other words, general interfaces with little casting are always preferable over more specific interfaces causing more casting. This improves the ability of disjoint components to remain interchangeable. For example, interchanging a JDBC connection pool with a JNDI contexts component. The Implementation: Curiously, the implementation of this proposal involves almost no non-interface or non-abstract classes. A loosely coupled framework should and will allow implementors to add advances as much as they want, provided the interface definition and the spirit of that definition is not modified. Avalon Extensions ----------------- The basic component design should be fueled by the Block pattern in Avalon. From this we devise org.apache.?.Component. Note that we are using Component to denote both projects (such as the org.apache.* family) as well as what are traditionally considered application services. This is to facilitate the thinning line between those two. For example, treatment of a procedure over XML-RPC, traditionally considered a service, is close to the behavior of treatment of a function through the Cocoon sitemap. In both cases, an arbitray input and output is defined, and the application assembler should not have to know the intricacies of the interaction. For any given component, the component must be able to accept a singular Object as input and return a singular Object as output. This is an additional requirement that originally in Avalon. This provides for runtime handling of objects while maintaining a generic interface across Components. For example: package org.apache.?.Component; import org.apache.avalon.Block; public interface Component extends Block { public void set(Object ob); public Object get(); } By providing these accessors and mutators, it is possible to pipe output from one component into the input of another. The object being passed can then be runtime discovered and casted as appropriate. This is critical to flexibility in implementation. Consider a ConnectionPool component. The object returned may be a java.sql.Connection. However, it may be a java.sql.PooledConnection, or my.package.PooledConnection. By not forcing syntax into the interfaces, developers are able to be as clever in implementation as they choose. In addition, as I pointed out earlier, the introduction of proxying from other components, say an XML-RPC component that behind the scenes handles network communication, becomes possible without assemblers needing to know the details. In addition, some mechanism for execution is needed. This method should _never_ require the passing in of additional parameters, and should always somply return a boolean indicating if it succeeded (executing, not success as in "login successful"). This allows a generic execute, and if input is needed, it should be provided via the set(Object ob) mechanism. I am still working on my ideas for this, so I do not include it here. Certainly the obvious idea is: public boolean execute() throws AppException; Current Cocoon Structures ------------------------- As a test bed, we should retrofit existing Cocoon constructs into Components (Processors, Producers). Then we use org.apache.cocoon.Cocoon as a framework, and a producer becomes the control structure. This describes our original model. Interchanging processors (DCP, SQL, etc.) is a sufficient test. Additionally, introducing components that are of neither Processor or Producer flavor (the JDBC connection pooling requested, for example) will extend our understanding of this model. As each component is introduced, at least two varying implementations should be provided and tested for inclusion as a new Component implementation, and a successful test of the design. I also propose we add a org.apache.cocoon.Sitemap which begins to use these components. While this may not initially exactly match the sitemap proposal, it merges these two ideas. The ultimate end is that org.apache.cocoon.Cocoon and org.apache.cocoon.Sitemap can work hand in hand. At this point we have reached the maturity for tackling larger integration efforts with products such as Turbine, etc. XML/XSP/Data Model ------------------ For each component, sufficient design of interfaces to allow use from an XSP tag library is required. This ensures that our components are not Java-centric, but purpose-centric. If an XSP page (radically different in architecture than a servlet) can readily use a given component, that is significant in the components' evolution. Feedback -------- This is an initial model, partially realized in my mind. It is based heavily on Avalon, personal frameworks, and a dissatisfaction with the time spent to uncouple applications, or force users into _one_ (and only one) solution. Right now, Cocoon and Turbine are two good solutions that are close to mutually exclusive; they certainly do not fit together well. My experiences here intergrating the two (and rolling out a production application on Cocoon and a similar framework) are shown here. Certainly it is not foolproof though, and I welcome all feedback. Have at it, tear it up... -Brett