You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@turbine.apache.org by Jon Stevens <jo...@latchkey.com> on 2001/08/13 06:17:54 UTC

[HOWTO] Extend TurbineUser with your own class...

I'm deep in this stuff right now in Scarab, so I'm going to quickly document
it because it comes up quite frequently on the list. If someone wants to
contribute a cleaned up version as an xdoc, that would be most excellent.

Define your User in your schema.xml file:

<table name="SCARAB_USER" javaName="ScarabUserImpl" alias="TurbineUser"
    baseClass="org.apache.fulcrum.security.impl.db.entity.TurbineUser"
    basePeer="org.apache.fulcrum.security.impl.db.entity.TurbineUserPeer">
    <!--
        Unique identifier.
    -->
    <column name="USER_ID" primaryKey="true" required="true"
type="INTEGER"/>
</table>

You only need to define the columns in which you are referring to as a
foreign key elsewhere in your database. In our case, that is just USER_ID.

Create an interface which describes the additional methods you are adding to
your User object:

public interface ScarabUser extends User

Have Torque create an implementation of ScarabUser. You should then fill it
with the methods that you defined in ScarabUser. It should extend the Base
class and look something like this:

public class ScarabUserImpl extends BaseScarabUserImpl implements ScarabUser

Have Torque create the appropriate Peer class (mine is empty so far):

public class ScarabUserImplPeer
    extends org.tigris.scarab.om.BaseScarabUserImplPeer
{
}

In your TurbineResources.properties file modify the following properties to
tell Turbine to point at your specific implementations of the User
interface:

services.SecurityService.user.class=org.tigris.scarab.om.ScarabUserImpl
services.SecurityService.userPeer.class=org.tigris.scarab.om.ScarabUserImplP
eer

Lastly, in your application code, you should *always* refer (ie: cast) to
your specific interface. For example:

ScarabUser su = (ScarabUser) TurbineSecurity.getUser(1);

As you can see, it isn't real hard to override Turbine's concept of a User
with your own specific implementation. If you wish to rename column names
and what not, then you will need to do a bit more work and is beyond the
scope of this tutorial.

Thanks!

-jon


---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-user-help@jakarta.apache.org


Re: [HOWTO] Extend TurbineUser with your own class...

Posted by Scott Eade <se...@backstagetech.com.au>.
Like Claudio, I too am attempting to extend TurbineUser.

I am aiming to keep this simple by trailing an implementation using
newapp before I try this out on a larger application.  This is a long
winded message because I want to try and get the root of the
problems to see if we can add to the HOWTO and make it more
useful.  Note that I have had a good look at Scarab but the
generated classes do not appear to be in CVS so it does not
provide as much help as I had hoped.

I think there are two objectives most people have in mind when
they express a desire to extend TurbineUser:
1. They want to be able to make use of TURBINE_USER.USER_ID
as a foreign key in application tables.
2. They want to add columns to TURBINE_USER representing
additional user attributes.

My simple changes to newapp to test this out are:
1. Adding a CREATE_USER_ID column to the RDF table.
2. Adding a TITLE column to TURBINE_USER.

I believe I have done everything the HOWTO and the follow-up
messages suggest:

newapp-schema.xml reads as follows (note the addition of
CREATE_USER_ID to the table RDF and the use of
the turbine 2.1 classes):

<database>
  <table name="NEWAPP_USER" javaName="NewappUserImpl" alias="TurbineUser"
    baseClass="org.apache.turbine.om.security.TurbineUser"
    basePeer="org.apache.turbine.om.security.peer.TurbineUserPeer">
    <!-- Unique identifier -->
    <column name="USER_ID" primaryKey="true" required="true" type="integer"/>
  </table>

  <table name="RDF" idMethod="autoincrement">
    <column name="RDF_ID" required="true" autoIncrement="true" primaryKey="true" type="INTEGER"/>
    <column name="TITLE" size="255" type="VARCHAR"/>
    <column name="BODY" size="255" type="VARCHAR"/>
    <column name="URL" size="255" type="VARCHAR"/>
    <column name="AUTHOR" size="255" type="VARCHAR"/>
    <column name="DEPT" size="255" type="VARCHAR"/>
    <column name="CREATE_USER_ID" required="true" type="INTEGER"/>
    <foreign-key foreignTable="NEWAPP_USER">
      <reference local="CREATE_USER_ID" foreign="USER_ID"/>
    </foreign-key>
  </table>
</database>

turbine-schema.xml now includes (note the addition of the
TITLE column to TURBINE_USER):

  <table name="TURBINE_USER" idMethod="idbroker">
    <column name="USER_ID" required="true" primaryKey="true" type="INTEGER"/>
    <column name="LOGIN_NAME" required="true" size="32" type="VARCHAR"/>
    <column name="PASSWORD_VALUE" required="true" size="32" type="VARCHAR"/>
    <column name="FIRST_NAME" required="true" size="99" type="VARCHAR"/>
    <column name="LAST_NAME" required="true" size="99" type="VARCHAR"/>
    <column name="EMAIL" size="99" type="VARCHAR"/>
    <column name="CONFIRM_VALUE" size="99" type="VARCHAR"/>
    <column name="TITLE" size="99" type="VARCHAR"/> <!-- Added by Scott -->
    <column name="MODIFIED" type="TIMESTAMP"/>
    <column name="CREATED" type="TIMESTAMP"/>
    <column name="LAST_LOGIN" type="TIMESTAMP"/>
    <column name="OBJECTDATA" type="VARBINARY"/>
    <unique>
        <unique-column name="LOGIN_NAME"/>
    </unique>
  </table>

The trouble is that when I ant init newapp, the compile step falls over
because getUserId() is not defined in BaseNewappImpl. According
to the HOWTO I would have NewappUserImpl implement my
NewappUser interface (see below) but this won't fix the errors.

Here are the errors:

compile:
    [javac] Compiling 6 source files to F:\tdk\webapps\newapp\WEB-INF\classes
    [javac] F:\tdk\webapps\newapp\WEB-INF\src\java\org\mycompany\newapp\om\BaseNewappUserImpl.java:115: cannot resolve
symbol
    [javac] symbol  : method getUserId  ()
    [javac] location: class org.mycompany.newapp.om.BaseNewappUserImpl
    [javac]                    criteria.add(RdfPeer.CREATE_USER_ID, getUserId() );
    [javac]                                                         ^
    [javac] F:\tdk\webapps\newapp\WEB-INF\src\java\org\mycompany\newapp\om\BaseNewappUserImpl.java:137: cannot resolve
symbol
    [javac] symbol  : method getUserId  ()
    [javac] location: class org.mycompany.newapp.om.BaseNewappUserImpl
    [javac]                    criteria.add(RdfPeer.CREATE_USER_ID, getUserId() );
    [javac]                                                         ^
    [javac] F:\tdk\webapps\newapp\WEB-INF\src\java\org\mycompany\newapp\om\BaseRdf.java:272: cannot resolve symbol
    [javac] symbol  : method getUserId  ()
    [javac] location: class org.mycompany.newapp.om.NewappUserImpl
    [javac]            setCreateUserId(v.getUserId());
    [javac]                             ^
    [javac] F:\tdk\webapps\newapp\WEB-INF\src\java\org\mycompany\newapp\om\BaseRdf.java:281: cannot resolve symbol
    [javac] symbol  : method retrieveByPK  (org.apache.turbine.om.NumberKey)
    [javac] location: class org.mycompany.newapp.om.NewappUserImplPeer
    [javac]             aNewappUserImpl = NewappUserImplPeer.retrieveByPK(this.create_user_id);
    [javac]                                                 ^
    [javac] 4 errors

BUILD FAILED

My NewappUser interface contains:

    package org.mycompany.newapp.om.security;

    import org.apache.turbine.om.security.User;
    import org.apache.turbine.om.NumberKey;

    public interface NewappUser extends User
    {
        public String getTitle();
        public void setTitle(String title);
        public NumberKey getUserId();
    }

But as already mentioned, having NewappUserImpl extend this
class is ineffectual because the compile errors require additional
code down a level in BaseNewappUserImpl.

Now tofupup@austin.rr.com suggested a different way out
where instead of defining an interface he/she instead edited the
Base classes generated by torque so that the equivalent of my
BaseNewappUserImpl has this method:

    public NumberKey getUserId()
    {
        return (NumberKey)getPrimaryKey();
    }

And BaseNewappUserImpl has these two:

    public static NewappUserImpl retrieveByPK(ObjectKey pk)
    public static NewappUserImpl retrieveByPK( ObjectKey pk, DBConnection dbcon )

With these changes everything compiles cleanly, but won't I lose these
changes if I init newapp again?  Doesn't this point to a bug in torque
whereby it should be generating this code for primary key columns
defined in alias tables?

To try trhese changes out I change the following two lines in TR.props:

    services.SecurityService.user.class=org.mycompany.newapp.om.NewappUserImpl
    services.SecurityService.userPeer.class=org.mycompany.newapp.om.NewappUserImplPeer

With these changes my newapp can be modified to store the UserId
of the NewappUser that creates the RDF record and the torque
generated method RdfPeer.getNewappUserImpl() works as desired
- i.e. We have achieved the first objective of being able to use the
UserId as a foreign key in an application table.


Now on to the second desired extension - i.e. storing additional
user attributes in TurbineUser.

The HOWTO indicates that I should modify the torque generated
NewappUserImpl and have it implement the interface that defined
the additional attributes I want to add to TurbineUser (this is
NewappUser defined above).  So I end up with:

    public  class NewappUserImpl
        extends org.mycompany.newapp.om.BaseNewappUserImpl
        implements Persistent, NewappUser
    ...

The problem I run into here is that I have no idea how I should
go about implementing the getTitle() and setTitle() methods for
the additional attribute in NewappUserImpl.  I can't see anything
generated by torque that provides any help, and the classes that
are part of Turbine are quite different to those generated by torque
for standard application tables, so the approach I should take
is not quite obvious.

Can anyone give me a clue here to get me going?


I'd really like to sort these issues out so that we can enhance the
HOWTO to deal with these two points - they are after all the
basic motivations behind the desire to extend TurbineUser (are
there others I am missing)?.

Help gladly accepted with thanks.

Scott

----- Original Message -----
From: "Jon Stevens" <jo...@latchkey.com>
To: "turbine-dev" <tu...@jakarta.apache.org>; "Turbine-user" <tu...@jakarta.apache.org>
Sent: Monday, August 13, 2001 2:17 PM
Subject: [HOWTO] Extend TurbineUser with your own class...


> I'm deep in this stuff right now in Scarab, so I'm going to quickly document
> it because it comes up quite frequently on the list. If someone wants to
> contribute a cleaned up version as an xdoc, that would be most excellent.
>
> Define your User in your schema.xml file:
>
> <table name="SCARAB_USER" javaName="ScarabUserImpl" alias="TurbineUser"
>     baseClass="org.apache.fulcrum.security.impl.db.entity.TurbineUser"
>     basePeer="org.apache.fulcrum.security.impl.db.entity.TurbineUserPeer">
>     <!--
>         Unique identifier.
>     -->
>     <column name="USER_ID" primaryKey="true" required="true"
> type="INTEGER"/>
> </table>
>
> You only need to define the columns in which you are referring to as a
> foreign key elsewhere in your database. In our case, that is just USER_ID.
>
> Create an interface which describes the additional methods you are adding to
> your User object:
>
> public interface ScarabUser extends User
>
> Have Torque create an implementation of ScarabUser. You should then fill it
> with the methods that you defined in ScarabUser. It should extend the Base
> class and look something like this:
>
> public class ScarabUserImpl extends BaseScarabUserImpl implements ScarabUser
>
> Have Torque create the appropriate Peer class (mine is empty so far):
>
> public class ScarabUserImplPeer
>     extends org.tigris.scarab.om.BaseScarabUserImplPeer
> {
> }
>
> In your TurbineResources.properties file modify the following properties to
> tell Turbine to point at your specific implementations of the User
> interface:
>
> services.SecurityService.user.class=org.tigris.scarab.om.ScarabUserImpl
> services.SecurityService.userPeer.class=org.tigris.scarab.om.ScarabUserImplP
> eer
>
> Lastly, in your application code, you should *always* refer (ie: cast) to
> your specific interface. For example:
>
> ScarabUser su = (ScarabUser) TurbineSecurity.getUser(1);
>
> As you can see, it isn't real hard to override Turbine's concept of a User
> with your own specific implementation. If you wish to rename column names
> and what not, then you will need to do a bit more work and is beyond the
> scope of this tutorial.
>
> Thanks!
>
> -jon
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: turbine-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: turbine-user-help@jakarta.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-user-help@jakarta.apache.org