org.neuclear.id.builders.IdentityBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.neuclear.id.builders.IdentityBuilder.java

Source

/*
 * $Id: IdentityBuilder.java,v 1.30 2004/05/31 19:11:36 pelle Exp $
 * $Log: IdentityBuilder.java,v $
 * Revision 1.30  2004/05/31 19:11:36  pelle
 * Added working PublishAccountScreen
 * IdentityPanel now include Cut and Paste of URLS's
 * KeyStorePanel when used from within the PersonalTrader allows copying of entries. The entries are XMLSig KeyInfo objects.
 *
 * Revision 1.29  2004/05/27 19:51:48  pelle
 * The beginnings of the Create Account Page
 *
 * Revision 1.28  2004/05/26 19:28:54  pelle
 * Updated IdentityBuilder to change the html title
 * Changed the way url's are displayed.
 *
 * Revision 1.27  2004/04/28 00:24:05  pelle
 * Fixed the strange verification error
 * Added bunch of new unit tests to support this.
 * Updated Signer's dependencies and version number to be a 0.9 release.
 * Implemented ThreadLocalSession session management for Hibernate ledger.
 * Various other minor changes.
 *
 * Revision 1.26  2004/04/26 23:58:04  pelle
 * Trying to find the verifying error
 *
 * Revision 1.25  2004/04/23 23:34:03  pelle
 * Major update. Added an original url and nickname to Identity and friends.
 *
 * Revision 1.24  2004/04/19 18:44:16  pelle
 * Stores a cache on disk
 *
 * Revision 1.23  2004/04/18 01:05:15  pelle
 * Forgot to add the <meta name="neu:type" content="Identity"/> tag to files generated by IdentityBuilder and it's sub classes.
 *
 * Revision 1.22  2004/04/17 19:28:21  pelle
 * Identity is now fully html based as is the ServiceBuilder.
 * VerifyingReader correctly identifies html files and parses them as such.
 * Targets and Target now parse html link tags
 * AssetBuilder and ExchangeAgentBuilder have been updated to support it and provide html formatted contracts.
 * The Asset.Reader and ExchangeAgent.Reader still need to be updated.
 *
 * Revision 1.21  2004/04/01 23:19:47  pelle
 * Split Identity into Signatory and Identity class.
 * Identity remains a signed named object and will in the future just be used for self declared information.
 * Signatory now contains the PublicKey etc and is NOT a signed object.
 *
 * Revision 1.20  2004/03/22 20:09:43  pelle
 * Added simple ledger for unit testing and in memory use
 *
 * Revision 1.19  2004/02/18 00:14:30  pelle
 * Many, many clean ups. I've readded Targets in a new method.
 * Gotten rid of NamedObjectBuilder and revamped Identity and Resolvers
 *
 * Revision 1.18  2004/01/13 15:11:35  pelle
 * Now builds.
 * Now need to do unit tests
 *
 * Revision 1.17  2004/01/07 23:12:20  pelle
 * XMLSig now has various added features:
 * -  KeyInfo supports X509v3 (untested)
 * -  KeyInfo supports KeyName
 * -  When creating a XMLSignature and signing it with a Signer, it adds the alias to the KeyName
 * Added KeyResolver interface and KeyResolverFactory Class. At the moment no implementations.
 *
 * Revision 1.16  2003/12/19 18:03:34  pelle
 * Revamped a lot of exception handling throughout the framework, it has been simplified in most places:
 * - For most cases the main exception to worry about now is InvalidNamedObjectException.
 * - Most lowerlevel exception that cant be handled meaningful are now wrapped in the LowLevelException, a
 *   runtime exception.
 * - Source and Store patterns each now have their own exceptions that generalizes the various physical
 *   exceptions that can happen in that area.
 *
 * Revision 1.15  2003/12/18 17:40:19  pelle
 * You can now create keys that get stored with a X509 certificate in the keystore. These can be saved as well.
 * IdentityCreator has been modified to allow creation of keys.
 * Note The actual Creation of Certificates still have a problem that will be resolved later today.
 *
 * Revision 1.14  2003/12/16 15:04:59  pelle
 * Added SignedMessage contract for signing simple textual contracts.
 * Added NeuSender, updated SmtpSender and Sender to take plain email addresses (without the mailto:)
 * Added AbstractObjectCreationTest to make it quicker to write unit tests to verify
 * NamedObjectBuilder/SignedNamedObject Pairs.
 * Sample application has been expanded with a basic email application.
 * Updated docs for simple web app.
 * Added missing LGPL LICENSE.txt files to signer and simple app
 *
 * Revision 1.13  2003/12/11 23:57:29  pelle
 * Trying to test the ReceiverServlet with cactus. Still no luck. Need to return a ElementProxy of some sort.
 * Cleaned up some missing fluff in the ElementProxy interface. getTagName(), getQName() and getNameSpace() have been killed.
 *
 * Revision 1.12  2003/12/11 16:29:26  pelle
 * Updated various builders to use the new helper methods in AbstractElementProxy hopefully making them more readable.
 *
 * Revision 1.11  2003/12/11 16:16:14  pelle
 * Some changes to make the xml a bit more readable.
 * Also added some helper methods in AbstractElementProxy to make it easier to build objects.
 *
 * Revision 1.10  2003/12/10 23:58:51  pelle
 * Did some cleaning up in the builders
 * Fixed some stuff in IdentityCreator
 * New maven goal to create executable jarapp
 * We are close to 0.8 final of ID, 0.11 final of XMLSIG and 0.5 of commons.
 * Will release shortly.
 *
 * Revision 1.9  2003/12/08 19:32:31  pelle
 * Added support for the http scheme into ID. See http://neuclear.org/archives/000195.html
 *
 * Revision 1.8  2003/11/21 04:45:10  pelle
 * EncryptedFileStore now works. It uses the PBECipher with DES3 afair.
 * Otherwise You will Finaliate.
 * Anything that can be final has been made final throughout everyting. We've used IDEA's Inspector tool to find all instance of variables that could be final.
 * This should hopefully make everything more stable (and secure).
 *
 * Revision 1.7  2003/11/11 21:18:42  pelle
 * Further vital reshuffling.
 * org.neudist.crypto.* and org.neudist.utils.* have been moved to respective areas under org.neuclear.commons
 * org.neuclear.signers.* as well as org.neuclear.passphraseagents have been moved under org.neuclear.commons.crypto as well.
 * Did a bit of work on the Canonicalizer and changed a few other minor bits.
 *
 * Revision 1.6  2003/11/10 21:08:49  pelle
 * More JavaDoc
 *
 * Revision 1.5  2003/10/29 21:16:27  pelle
 * Refactored the whole signing process. Now we have an interface called Signer which is the old SignerStore.
 * To use it you pass a byte array and an alias. The sign method then returns the signature.
 * If a Signer needs a passphrase it uses a PassPhraseAgent to present a dialogue box, read it from a command line etc.
 * This new Signer pattern allows us to use secure signing hardware such as N-Cipher in the future for server applications as well
 * as SmartCards for end user applications.
 *
 * Revision 1.4  2003/10/21 22:31:12  pelle
 * Renamed NeudistException to NeuClearException and moved it to org.neuclear.commons where it makes more sense.
 * Unhooked the XMLException in the xmlsig library from NeuClearException to make all of its exceptions an independent hierarchy.
 * Obviously had to perform many changes throughout the code to support these changes.
 *
 * Revision 1.3  2003/10/02 23:29:03  pelle
 * Updated Root Key. This will be the root key for the remainder of the beta period. With version 1.0 I will update it with a new key.
 * VerifyingTest works now and also does a pass for fake ones. Will have to think of better ways of making fake Identities to break it.
 * Cleaned up much of the tests and they all pass now.
 * The FileStoreTests need to be rethought out, by adding a test key.
 *
 * Revision 1.2  2003/10/01 19:08:30  pelle
 * Changed XML Format. Now NameSpace has been modified to Identity also the
 * xml namespace prefix nsdl has been changed to neuid.
 * The standard constants for using these have been moved into NSTools.
 * The NamedObjectBuilder can also now take an Element, such as an unsigned template.
 *
 * Revision 1.1  2003/09/27 19:23:11  pelle
 * Added Builders to create named objects from scratch.
 *
 * Revision 1.11  2003/02/18 14:57:18  pelle
 * Finished Cleaning up Receivers and Stores.
 * Also updated nsdl.xsd xml schema with latest changes.
 * The whole API is now very simple.
 *
 * Revision 1.10  2003/02/18 00:06:15  pelle
 * Moved the Signer's into xml-sig
 *
 * Revision 1.9  2003/02/16 00:22:59  pelle
 * LogSender now works and there is a corresponding server side cgi script to do the logging in
 * http://neuclear.org/logger/ Site is not yet up but will be soon.
 *
 * Revision 1.8  2003/02/14 21:10:29  pelle
 * The email sender works. The LogSender and the SoapSender should work but havent been tested yet.
 * The NamedObject has a new log() method that logs it's contents at it's parent NameSpace's logger.
 * The NameSpace object also has a new method receive() which allows one to receive a named object to the NameSpace's
 * default receiver.
 *
 * Revision 1.7  2003/02/10 22:30:05  pelle
 * Got rid of even further dependencies. In Particular OSCore
 *
 * Revision 1.6  2003/02/09 00:15:52  pelle
 * Fixed things so they now compile with r_0.7 of XMLSig
 *
 * Revision 1.5  2003/01/16 22:20:02  pelle
 * First Draft of new generalised Ledger Interface.
 * Currently we have a Book and Transaction class.
 * We also need a Ledger class and a Ledger Factory.
 *
 * Revision 1.4  2002/12/17 21:40:54  pelle
 * First part of refactoring of NamedObject and SignedObject Interface/Class parings.
 *
 * Revision 1.3  2002/12/17 20:34:39  pelle
 * Lots of changes to core functionality.
 * First of all I've refactored most of the Resolving and verification code. I have a few more things to do
 * on it before I'm happy.
 * There is now a NSResolver class, which handles all the namespace resolution. I took most of the functionality
 * for this out of NamedObject.
 * Then there is the veriifer, which verifies a given NamedObject using the NSResolver.
 * This has simplified the NamedObject classes drastically, leaving them as mainly data objects, which is what they
 * should be.
 * I have also gone around and tightened up security on many different classes, making clases and/or methods final where appropriate.
 * NSCache now operates using http://www.waterken.com's fantastic ADT collections library.
 * Something important has been added, which is a SignRequest named object. This signed object, embeds an unsigned
 * named object for signing by an end users' signing service.
 * Now were almost ready to start seriously implementing AssetIssuers and Transfers, which will be the most important
 * part of the framework.
 *
 * Revision 1.2  2002/10/02 21:03:44  pelle
 * Major Commit
 * I completely redid the namespace resolving code.
 * It now works correctly with the new store attribute of the namespace
 * And can correctly work out the location of a namespace file
 * by hierarchically signing it.
 * I have also included several top level namespaces and finalised
 * the root namespace.
 * In short all of the above means that we can theoretically call
 * Neubia live now. (Well on my first deployment anyway).
 * There is a new CommandLineSigner utility class which creates and signs
 * namespaces using standard java keystores.
 * I'm now working on updating the documentation, so other people
 * than me might have a chance at using it.
 *
 * Revision 1.1.1.1  2002/09/18 10:55:42  pelle
 * First release in new CVS structure.
 * Also first public release.
 * This implemnts simple named objects.
 * - NameSpace Objects
 * - NSAuth Objects
 *
 * Storage systems
 * - In Memory Storage
 * - Clear text file based storage
 * - Encrypted File Storage (with SHA256 digested filenames)
 * - CachedStorage
 * - SoapStorage
 *
 * Simple SOAP client/server
 * - Simple Single method call SOAP client, for arbitrary dom4j based requests
 * - Simple Abstract SOAP Servlet for implementing http based SOAP Servers
 *
 * Simple XML-Signature Implementation
 * - Based on dom4j
 * - SHA-RSA only
 * - Very simple (likely imperfect) highspeed canonicalizer
 * - Zero support for X509 (We dont like that anyway)
 * - Super Simple
 *
 *
 * Revision 1.5  2002/06/18 03:04:11  pelle
 * Just added all the necessary jars.
 * Fixed a few things in the framework and
 * started a GUI Application to manage Neu's.
 *
 * Revision 1.4  2002/06/17 20:48:33  pelle
 * The NS functionality should now work. FileStore is working properly.
 * The example .ns objects in the neuspace folder have been updated with the
 * latest version of the format.
 * "neuspace/root.ns" should now be considered the universal parent of the
 * neuclear system.
 * Still more to go, but we're getting there. I will now focus on a quick
 * Web interface. After which Contracts will be added.
 *
 * Revision 1.3  2002/06/13 19:04:07  pelle
 * A start to a web interface into the architecture.
 * We're getting a bit further now with functionality.
 *
 * Revision 1.2  2002/06/05 23:42:04  pelle
 * The Throw clauses of several method definitions were getting out of hand, so I have
 * added a new wrapper exception NeuClearException, to keep things clean in the ledger.
 * This is used as a catchall wrapper for all Exceptions in the underlying API's such as IOExceptions,
 * XML Exceptions etc.
 * You can catch any Exception and rethrow it using Utility.rethrowException(e) as a quick way of handling
 * exceptions.
 * Otherwise the Store framework and the NameSpaces are really comming along quite well. I added a CachedStore
 * which wraps around any other Store and caches the access to the store.
 *
 * Revision 1.1.1.1  2002/05/29 10:02:22  pelle
 * Lets try one more time. This is the first rev of the next gen of Neudist
 *
 *
 */
package org.neuclear.id.builders;

import org.dom4j.Attribute;
import org.dom4j.Element;
import org.neuclear.commons.Utility;
import org.neuclear.commons.crypto.passphraseagents.swing.SwingAgent;
import org.neuclear.commons.crypto.signers.DefaultSigner;
import org.neuclear.id.Identity;
import org.neuclear.id.verifier.VerifyingReader;
import org.neuclear.xml.XMLTools;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class IdentityBuilder extends Builder {

    public IdentityBuilder(final String url) {
        this(TYPENAME, url);
    }

    /**
     * This constructor should be used by subclasses of Identity. It creates a Standard Identity document, but doesn't sign it.
     *
     * @param receiver URL of default receiver for namespace
     */
    public IdentityBuilder(final String name, final String url, final String receiver, final String message) {
        this(url);
        if (receiver != null)
            addTarget(receiver, "receiver");
        if (name != null) {
            head.addElement("title").setText("NeuClear Account Page for " + name);
            nickname = body.addElement("h1");
            nickname.setText(name);
            nickname.addAttribute("id", "nickname");
        }
        if (message != null)
            body.addElement("p").setText(message);

    }

    /**
     * This constructor should be used by subclasses of Identity. It creates a Standard Identity document, but doesn't sign it.
     *
     * @param type The type identifier
     */
    protected IdentityBuilder(String type, String url) {
        super("html");

        head = getElement().addElement("head");
        body = getElement().addElement("body");
        Element meta = head.addElement("meta");
        meta.addAttribute("name", "neu:type");
        meta.addAttribute("content", type);

        original = addLink("original", url).attribute("href");

        Element csselem = addLink("stylesheet", "/styles.css");
        csselem.addAttribute("type", "text/css");
        stylesheet = csselem.attribute("href");
    }

    protected final void addTarget(final String href, final String type) {
        if (!Utility.isEmpty(href)) {
            addLink("neu:" + type, href);
        }
    }

    public Element addLink(final String type, final String href) {
        final Element target = head.addElement("link");
        target.addAttribute("rel", type);
        target.addAttribute("href", href);
        return target;
    }

    public void addBlock(String id, String title, String value) {
        if (Utility.isEmpty(value))
            return;
        Element block = body.addElement("div");
        block.addElement("h3").setText(title);
        Element p = block.addElement("p");
        p.addAttribute("id", id);
        p.setText(value);
    }

    public void addImage(String id, String value) {
        if (Utility.isEmpty(value))
            return;
        Element image = body.addElement("img");
        image.addAttribute("id", id);
        image.addAttribute("src", value);
    }

    public void addInfo(String id, String title, String value) {
        if (Utility.isEmpty(value))
            return;
        Element block = body.addElement("p");
        block.addElement("b").setText(title + ": ");
        Element p = block.addElement("div");
        p.addAttribute("id", id);
        p.setText(value);
    }

    public void addWebLink(String id, String title, String value) {
        if (Utility.isEmpty(value))
            return;
        Element block = body.addElement("p");
        block.addElement("b").setText(title + ": ");
        Element p = block.addElement("a");
        p.addAttribute("id", id);
        p.addAttribute("href", value);
        p.setText(value);
    }

    public void addAddContactLink() {
        Element p = body.addElement("a");
        p.addAttribute("href", "http://localhost:11870/AddContact?" + getOriginal());
        p.addElement("img").addAttribute("src", "http://pkyp.org/images/contact_new.png");
        p.addText("Add to contacts in Personal Trader");
    }

    public void addEmail(String id, String title, String value) {
        if (Utility.isEmpty(value))
            return;
        Element block = body.addElement("p");
        block.addElement("b").setText(title + ": ");
        Element p = block.addElement("a");
        p.addAttribute("id", id);
        p.addAttribute("href", "mailto:" + value);
        p.setText(value);
    }

    public void setStylesheet(String href) {
        stylesheet.setValue(href);
    }

    public String getStylesheet() {
        return stylesheet.getValue();
    }

    public void setOriginal(String href) {
        original.setValue(href);
    }

    public String getOriginal() {
        return original.getValue();
    }

    public String getNickname() {
        if (nickname == null) {
            nickname = XMLTools.getByID(getElement(), "nickname");
            if (nickname == null)
                return "";
        }
        return nickname.getTextTrim();
    }

    public void setNickname(Element nickname) {
        if (this.nickname != null) {
            this.nickname.remove(this.nickname.attribute("id"));
        }
        this.nickname = nickname;
    }

    public void setNickname(String name) {
        if (this.nickname == null) {
            nickname = body.addElement("h1");
            nickname.addAttribute("id", "nickname");
        }
        nickname.setText(name);
    }

    public static void main(final String[] args) {
        try {
            final DefaultSigner signer = new DefaultSigner(new SwingAgent());

            final IdentityBuilder assetraw = new IdentityBuilder("Bob", "http://neuclear.org/bob.html",
                    "http://portfolio.neuclear.org", "Bobs ID");
            assetraw.sign(signer);
            //            System.out.println("Length:"+assetraw.asXML().length());
            File out = new File("src/testdata/simple/bob.html");
            out.getParentFile().mkdirs();
            XMLTools.writeFile(out, assetraw.getElement().getDocument());
            final InputStream is = new BufferedInputStream(new FileInputStream(out));
            final Identity asset = (Identity) VerifyingReader.getInstance().read(is);
            System.exit(0);

        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    protected final Element head;
    protected final Element body;
    protected Element nickname;
    protected Attribute stylesheet;
    protected Attribute original;

    private static final String TYPENAME = "identity";

}