Logo von Guschtel.de Nicht eingeloggt.  
Main |  Privat |  Linux |  Clausthal |  Studium |  Stuff |  UniInfos II |  Userbereich |  Block |  Admin | 

 
Sie sind hier: Main > Linux > Cocoon, OJB and JDO with Cforms
KrabbelViech

Cocoon, OJB and JDO with Cforms

Content

Decomposed m:n Relationship

  • Database Design
  • Java Classes
  • package.jdo
  • repository.xml
  • Flow
  • Cforms Definition
  • Cforms Binding
  • Cforms Template

Database Design

/*
* Table Profile
*/

CREATE TABLE profiles (
	id INT8 DEFAULT nextval('profiles_id_seq'::text) NOT NULL,
	name VARCHAR(255) NOT NULL,
	CONSTRAINT profiles_id_pkey PRIMARY KEY(id),
	CONSTRAINT profiles_name_ukey UNIQUE(name)
);

CREATE SEQUENCE profiles_id_seq start 1 increment 1 maxvalue 9223372036854775807 minvalue 1 cache 1;

/*
* Table Menu Categories
*/

CREATE TABLE menu_categories (
	id INT8 DEFAULT nextval('menu_categories_id_seq'::text) NOT NULL,
	name VARCHAR(255) NOT NULL,
	CONSTRAINT menu_categories_id_pkey PRIMARY KEY(id),
	CONSTRAINT menu_categories_name_ukey UNIQUE(name)
);

CREATE SEQUENCE menu_categories_id_seq start 1 increment 1 maxvalue 9223372036854775807 minvalue 1 cache 1;

/*
* Table rel_profiles_menu_categories
*/

CREATE TABLE rel_profiles_menu_categories (
 	id INT8 DEFAULT nextval('rel_profiles_menu_categories_id_seq'::text) NOT NULL,
 	profile_id INT8 NOT NULL,
	menu_category_id INT8 NOT NULL,
 	sortnumber INT8 NOT NULL,
	CONSTRAINT rel_profiles_menu_categories_id_pkey PRIMARY KEY(id),
	CONSTRAINT rel_profiles_menu_categories_profile_id_fkey FOREIGN KEY(profile_id) REFERENCES profiles (id),
	CONSTRAINT rel_profiles_menu_categories_menu_category_id_fkey FOREIGN KEY(menu_category_id) REFERENCES menu_categories (id)
);

CREATE SEQUENCE rel_profiles_menu_categories_id_seq start 1 increment 1 maxvalue 9223372036854775807 minvalue 1 cache 1;

Java Classes

/**
* Profile.java
*/

package papillon;

import java.util.ArrayList;
import java.util.Collection;

import java.io.Serializable;

public class Profile implements Serializable {
        private int id;
        private Collection profileMenuCategories = new ArrayList ();
        private String name;

        public int getId () { 
		return id; 
	}
        public void setId (int id) { 
		this.id = id; 
	}

        public Collection getProfileMenuCategories () { 
		return profileMenuCategories; 
	}
        public void setProfileMenuCategories (Collection profileMenuCategories) { 
		this.profileMenuCategories = profileMenuCategories; 
	}
        public void addProfileMenuCategory (ProfileMenuCategory profileMenuCategory) {
                profileMenuCategory.setProfile (this);
                this.profileMenuCategories.add (profileMenuCategory);
        }
        public String getName () { 
		return name; 
	}
        public void setName (String name) {
		this.name = name;
	}
}

/**
* ProfileMenuCategory.java
*/

package papillon;

import java.io.Serializable;

public class ProfileMenuCategory implements Serializable {
        private int id;
	private int menucategory_id;
	private int profile_id;
        private Profile profile;
	private MenuCategory menucategory;
        private int sortnumber;

        public int getId () { 
		return id; 
	}
        public void setId (int id) { 
		this.id = id; 
	}
	
	
	
	
	public int getMenucategory_id () { 
		return menucategory_id; 
	}
        public void setMenucategory_id (int menucategory_id) { 
		this.menucategory_id = menucategory_id; 
	}
	public int getProfile_id () { 
		return profile_id; 
	}
        public void setProfile_id (int profile_id) { 
		this.profile_id = profile_id;
	}

	
	
	
        public Profile getProfile () { 
		return profile; 
	}
        public void setProfile (Profile profile) { 
		this.profile = profile; 
	}
	
	public MenuCategory getMenuCategory () { 
		return menucategory; 
	}
        public void setMenuCategory (MenuCategory menucategory) { 
		this.menucategory = menucategory; 
	}

        public int getSortnumber () { 
		return sortnumber; 
	}
        public void setSortnumber (int sortnumber) { 
		this.sortnumber = sortnumber; 
	}
}

/**
* MenuCategory.java
*/

package papillon;

import java.util.ArrayList;
import java.util.Collection;

import java.io.Serializable;

public class MenuCategory implements Serializable {
        private int id;
        private Collection profileMenuCategories = new ArrayList ();
        private String name;

        public int getId () { 
		return id; 
	}
        public void setId (int id) { 
		this.id = id; 
	}

        public Collection getProfileMenuCategories () { 
		return profileMenuCategories; 
	}
        public void setProfileMenuCategories (Collection profileMenuCategories) { 
		this.profileMenuCategories = profileMenuCategories; 
	}
        public void addProfileMenuCategory (ProfileMenuCategory profileMenuCategory) {
                profileMenuCategory.setMenuCategory (this);
                this.profileMenuCategories.add (profileMenuCategory);
        }
        public String getName () { 
		return name; 
	}
        public void setName (String name) {
		this.name = name;
	}
}

package.jdo

		<!-- Profile -->
		<class name="Profile" identity-type="datastore">
                        <field name="id" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="id"/>
                        </field>
                        <field name="name" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="name"/>
                        </field>
                        <field name="profileMenuCategories" embedded="true">
                                <collection embedded-element="true" />
                        </field>
                </class>
                <class name="ProfileMenuCategory" identity-type="datastore">
                        <field name="id" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="id"/>
                        </field>
			<field name="profile_id" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="profile_id"/>
                        </field>
			<field name="menucategory_id" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="menu_category_id"/>
                        </field>
                        <field name="profile" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="profile_id"/>
                        </field>
			<field name="menucategory" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="menu_category_id"/>
                        </field>
                        <field name="sortnumber" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="sortnumber"/>
                        </field>
                </class>
		<class name="MenuCategory" identity-type="datastore">
                        <field name="id" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="id"/>
                        </field>
                        <field name="name" persistence-modifier="persistent">
                                <extension vendor-name="ojb" key="column" value="name"/>
                        </field>
                        <field name="profileMenuCategories" embedded="true">
                                <collection embedded-element="true" />
                        </field>
                </class>

repository.xml

	<class-descriptor class="papillon.Profile" table="profiles">
                <field-descriptor name="id" primarykey="true" nullable="false" default-fetch="true" autoincrement="true" column="id" sequence-name="profiles_id_seq" jdbc-type="INTEGER"/>
                <field-descriptor name="name" default-fetch="true" column="name" jdbc-type="VARCHAR"/>
                <collection-descriptor name="profileMenuCategories" element-class-ref="papillon.ProfileMenuCategory" auto-retrieve="true" auto-delete="true" auto-update="true">
                        <inverse-foreignkey field-ref="profile_id"/>
                </collection-descriptor>
        </class-descriptor>
	
        <class-descriptor class="papillon.ProfileMenuCategory" table="rel_profiles_menu_categories">
                <field-descriptor name="id" primarykey="true" nullable="false" default-fetch="true" column="id" jdbc-type="INTEGER" autoincrement="true" sequence-name="rel_profiles_menu_categories_id_seq" />
                <field-descriptor name="profile_id" nullable="false" default-fetch="true" column="profile_id" jdbc-type="INTEGER" />
		<field-descriptor name="menucategory_id" nullable="false" default-fetch="true" column="menu_category_id" jdbc-type="INTEGER" />
                <field-descriptor name="sortnumber" default-fetch="true" column="sortnumber" jdbc-type="INTEGER"/>
                <reference-descriptor name="profile" class-ref="papillon.Profile">
                        <foreignkey field-ref="profile_id" />
                </reference-descriptor>
		<reference-descriptor name="menucategory" class-ref="papillon.MenuCategory">
                        <foreignkey field-ref="menucategory_id" />
                </reference-descriptor>
        </class-descriptor>
	
	<class-descriptor class="papillon.MenuCategory" table="menu_categories">
                <field-descriptor name="id" primarykey="true" nullable="false" default-fetch="true" autoincrement="true" column="id" sequence-name="menu_categories_id_seq" jdbc-type="INTEGER"/>
                <field-descriptor name="name" default-fetch="true" column="name" jdbc-type="VARCHAR"/>
                <collection-descriptor name="profileMenuCategories" element-class-ref="papillon.ProfileMenuCategory" auto-retrieve="true" auto-delete="true" auto-update="true">
                        <inverse-foreignkey field-ref="profile_id"/>
                </collection-descriptor>
        </class-descriptor>

Flow

cocoon.load("resource://org/apache/cocoon/forms/flow/javascript/Form.js");
var data; // Form data for flow-jxpath

function starttest () {
	var factory = cocoon.getComponent(Packages.org.apache.cocoon.ojb.jdo.components.JdoPMF.ROLE);
        var dao = new Packages.papillon.SimpleDAO(factory, "cocoon");

        var profile = new Packages.papillon.Profile ();
	var menucategory = new Packages.papillon.MenuCategory();
        var pmc;
        var id;
        var iterator;
        // 1.
        // let's make a new bean with 1 child
        profile.setName ('Profile 1');
	menucategory.setName('MenuCategory 1');
	dao.insert (menucategory);
	dao.insert (profile);
	
	profile = dao.retrieve(profile);
	menucategory = dao.retrieve(menucategory);
	
        pmc = new Packages.papillon.ProfileMenuCategory ();
        pmc.setSortnumber (1);
	
        profile.addProfileMenuCategory (pmc);
	menucategory.addProfileMenuCategory (pmc);

        // 2.
        // let's save it
        dao.update (profile);
	dao.update (menucategory);

        // 3.
        // let's retrieve it from database
        id = profile.getId();
        profile = new Packages.papillon.Profile ();
        profile.setId(id);
        profile = dao.retrieve(profile);
        
        iterator=profile.getProfileMenuCategories().iterator();

        while (iterator.hasNext()) {
                pmc = iterator.next();
                pmc.setSortnumber (2);
        }

        // 4.
        // let's modify the bean

        profile.setName ('Profile 2');
        
        // let's save it to the database
        dao.update (profile);

        // and remove it from database
        dao.remove (profile);
	dao.remove (menucategory);

	cocoon.releaseComponent(factory);
        cocoon.redirectTo ("ok.html");
}



function getAllCategories() {
    var factory = cocoon.getComponent(Packages.org.apache.cocoon.ojb.jdo.components.JdoPMF.ROLE);
    var dao = new Packages.papillon.SimpleDAO(factory, "cocoon");
	
    var criteria = new Packages.org.apache.ojb.broker.query.Criteria();
    
    var query = Packages.org.apache.ojb.broker.query.QueryFactory.newReportQuery(Packages.papillon.MenuCategory, criteria);

    var attributes = new Array(1);
    attributes[0] = "count(*)";

    query.setAttributes(attributes);

    var cnt;
    dao.begin();
    var it = dao.getReport (query);
    while ( it.hasNext() == true) {
	var o = it.next();
	var count = o[0].intValue();
	cnt = count;
    }
    dao.commit();

    criteria = new Packages.org.apache.ojb.broker.query.Criteria();
    query = Packages.org.apache.ojb.broker.query.QueryByCriteria(Packages.papillon.MenuCategory,criteria);
    var cats = dao.retrieve(query);
    
    var cat = new Packages.papillon.MenuCategory();
    var id;
    var name;    
    var allcategories = new Array(count);

    for (var i=0; i < count; i++) {
	cat = cats.elementAt(i);
	id = cat.getId();
	name = cat.getName();
	allcategories[i] = new Object();
	allcategories[i].id = id;
	allcategories[i].name = name;
    }
    cocoon.releaseComponent(factory);    
    return allcategories;
}



function update_profile_widgets(form) {
	var profile_id = new Packages.java.lang.Integer(form.getChild("id").getValue().toString());
	var repeater = form.getChild("profileMenuCategories");
	for (var i = 0; i < repeater.size; i++) {
		repeater.getRow(i).lookupWidget("profile_id").setValue(profile_id);
		repeater.getRow(i).lookupWidget("sortnumber").setValue(new Packages.java.lang.Integer(i.toString()));
	}
}

function manage_profile() {
	var form = new Form("forms/definition/profile_definition.xml");
    	form.createBinding("forms/binding/profile_binding.xml");
	
	var action;
	var profile_id;
	var profile;
	
	// get all Categories
	data = new Object();
    	data.allcategories = getAllCategories();
	
	var factory = cocoon.getComponent(Packages.org.apache.cocoon.ojb.jdo.components.JdoPMF.ROLE);
        var dao = new Packages.papillon.SimpleDAO(factory, "cocoon");
	
	action = cocoon.request.get("action");
    	if (action == null || action == undefined) {
		action = "new";
    	} else {
		profile_id = cocoon.request.get("profile_id");
		if (profile_id == null || profile_id == undefined) {
			action = "new";
		}
	}
	
	profile = new Packages.papillon.Profile();
	if (action != "new") {
		// Get profile
		profile.setId(profile_id);
		profile = dao.retrieve(profile);
	}
	
	
	form.load(profile);
    	form.showForm("form-display-pipeline-profile",data);
    	form.save(profile);
	var profilename = profile.getName();
	if (action == "new") {
		dao.insert(profile);
	} else {
    		dao.update(profile);
	}
	
	cocoon.releaseComponent(factory);
        cocoon.redirectTo ("ok.html?profilname" + profilename);
}

CForms Definition

<?xml version="1.0"?>
<fd:form 
    xmlns:fd="http://apache.org/cocoon/forms/1.0#definition"
    >
    <fd:widgets>
    	<!-- wether to insert or to update the profile -->
    	<fd:field id="action">
	    <fd:datatype base="string" />
	</fd:field>
    
        <!-- Id of the Profile -->
        <fd:field id="id">
	    <fd:datatype base="integer" />
	</fd:field>
	
	<!-- name -->
	<fd:field id="name" required="true">
	    <fd:datatype base="string" />
	    <fd:label>Category-Name</fd:label>
	</fd:field>
	
	<!-- Categories -->
	<fd:repeater id="profileMenuCategories">
	    <fd:widgets>
	    	<fd:booleanfield id="select">
		    <fd:label>Select</fd:label>
		</fd:booleanfield>
	        <!-- Message -->
	        <fd:output id="message">
		    <fd:datatype base="string"/>
		</fd:output>
		<fd:field id="id">
		    <fd:datatype base="integer" />
		</fd:field>
	        <fd:field id="profile_id">
		    <fd:datatype base="integer" />
		</fd:field>
		<fd:field id="category_id">
		    <fd:label>Category</fd:label>
		    <fd:datatype base="integer"/>
		    <fd:selection-list type="flow-jxpath" list-path="allcategories" value-path="id" label-path="name" dynamic="true"/>
		    <fd:on-value-changed>
		        <javascript>
				update_profile_widgets(event.source.form);
			</javascript>
		    </fd:on-value-changed>
		</fd:field>
		<fd:field id="sortnumber">
		    <fd:datatype base="integer" />
		</fd:field>
		<fd:row-action id="add" action-command="add-after">
              	    <fd:label>+</fd:label>
		    <fd:on-action>
  		        <javascript>
				update_profile_widgets(event.source.form);
			</javascript>
		    </fd:on-action>
            	</fd:row-action>
            	<fd:row-action id="up" action-command="move-up">
                    <fd:label>^</fd:label>
		    <fd:on-action>
  		        <javascript>
				update_profile_widgets(event.source.form);
			</javascript>
		    </fd:on-action>
            	</fd:row-action>
            	<fd:row-action id="down" action-command="move-down">
              	    <fd:label>v</fd:label>
		    <fd:on-action>
  		        <javascript>
				update_profile_widgets(event.source.form);
			</javascript>
		    </fd:on-action>
            	</fd:row-action>
            	<fd:row-action id="delete" action-command="delete">
                    <fd:label>X</fd:label>
		    <fd:on-action>
  		        <javascript>
				update_profile_widgets(event.source.form);
			</javascript>
		    </fd:on-action>
            	</fd:row-action>
	    </fd:widgets>
	</fd:repeater>
	<fd:repeater-action id="addcategory" action-command="add-row" repeater="profileMenuCategories">
		<fd:label>New Category</fd:label>
		<fd:on-action>
  		        <javascript>
				update_profile_widgets(event.source.form);
			</javascript>
		    </fd:on-action>
	</fd:repeater-action>
	<fd:repeater-action id="removecategory" action-command="delete-rows" repeater="profileMenuCategories" select="select">
	    <fd:label>Remove Categories</fd:label>
	    <fd:on-action>
		<javascript>
			update_profile_widgets(event.source.form);
		</javascript>
	    </fd:on-action>
	</fd:repeater-action>
    </fd:widgets>
</fd:form>

CForms Binding

<?xml version="1.0"?>
<fb:context 
    xmlns:fb="http://apache.org/cocoon/forms/1.0#binding" path="/" 
    >

 <!-- Profile-Id -->
 <fb:value id="id" path="id" direction="load"/>
 <fb:value id="name" path="name" />
 
  <!-- Catgories -->
  <fb:repeater id="profileMenuCategories" parent-path="." row-path="profileMenuCategories">
    <fb:identity>
      <fb:value id="id" path="@id"/>
    </fb:identity>

    <fb:on-bind>
      <!-- executed on updates AND right after the insert -->
      <fb:value id="id" path="id" />
      <fb:value id="profile_id" path="profile_id" />
      <fb:value id="category_id" path="menucategory_id" />
      <fb:value id="sortnumber" path="sortnumber" />
    </fb:on-bind>
    
    <fb:unique-row>
      <fb:unique-field id="id" path="id"/>
    </fb:unique-row>

    <fb:on-delete-row>
        <fb:delete-node />
    </fb:on-delete-row>

    <fb:on-insert-row>
      <fb:insert-bean classname="papillon.ProfileMenuCategory" addmethod="addProfileMenuCategory" />
    </fb:on-insert-row>
    
    <fb:javascript id="profileMenuCategories" path="." direction="save">
  	<fb:save-form>
	var form = widget.form;
	update_profile_widgets(form);
	</fb:save-form>
    </fb:javascript>    
  </fb:repeater>

</fb:context>

CForms Template

<?xml version="1.0"?>
<page 
    xmlns:ft="http://apache.org/cocoon/forms/1.0#template" 
    xmlns:fi="http://apache.org/cocoon/forms/1.0#instance"
    >
  <title>New Profile</title>
  <content>
    <ft:form-template action="#{$continuation/id}.continue" method="POST">
      <ft:widget id="action">
          <fi:styling type="hidden" />
      </ft:widget>
      <!-- Id -->
      <ft:widget id="id">
          <fi:styling type="hidden" />
      </ft:widget>
      <table border="0">
      <!-- Name of the Profile -->
      <tr>
      <td>
      <ft:widget-label id="name"/>
      </td>
      <td>
      <ft:widget id="name"/>
      </td>
      </tr>
      
      <!-- Categories -->
      <tr>
      <td>
      Categories:<br />
      </td>
      <td>
      <table border="1">
      <tr>
        <th>id</th>
      	<th>profile_id</th>
	<th>sortnr</th>
         <th><ft:repeater-widget-label id="profileMenuCategories" widget-id="select"/></th>
         <th><ft:repeater-widget-label id="profileMenuCategories" widget-id="category_id"/></th>
	 <th>kram</th>
      </tr>
      <ft:repeater-widget id="profileMenuCategories">
      <tr>
      <td>
      	  <ft:widget id="id">
             <!--<fi:styling type="hidden" />-->
	  </ft:widget>
	  </td>
	  <td>
          <ft:widget id="profile_id">
             <!--<fi:styling type="hidden" />-->
	  </ft:widget>
	  </td>
	  <td>
	  <ft:widget id="sortnumber">
             <!--<fi:styling type="hidden" />-->
	  </ft:widget>
	  </td>
	  <td>
	     <ft:widget id="select" />
	  </td>
	  <td>
             <ft:widget id="category_id">
	         <fi:styling list-type="listbox" listbox-size="1" submit-on-change="true"/>
	     </ft:widget>
	     <ft:widget id="message"/>
	  </td>
	  <td>
	  <ft:widget id="up">
                            <fi:styling type="image" src="resources/move_up.gif"/>
                          </ft:widget>

                          <ft:widget id="down">
                            <fi:styling type="image" src="resources/move_down.gif"/>
                          </ft:widget>

                      <ft:widget id="delete">
                        <fi:styling type="image" src="resources/delete.gif"/>
                      </ft:widget>
                      <ft:widget id="add">
                        <fi:styling type="image" src="resources/new.gif"/>
                      </ft:widget>
	  </td>
      </tr>
      </ft:repeater-widget>
      <tr>
         <td>
	 <ft:widget id="addcategory"/>
	 </td>
	 <td>
	 <ft:widget id="removecategory"/>
	 </td>
      </tr>
      </table>
      </td>
      </tr>
      </table>
      <br />
      <input type="submit" />
    </ft:form-template>
  </content>
</page>




Main |  Privat |  Linux |  Clausthal |  Studium |  Stuff |  UniInfos II |  Userbereich |  Block |  Admin |   
Mittwoch, 23. Mai 2012 18:29:57 - http://old.guschtel.de/HP5/linux/ojbjdo_dmton.php - Impressum
krabbel