clerezza-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject [49/51] [partial] clerezza git commit: CLEREZZA-966: removed platform. prefix of folder names
Date Mon, 23 Mar 2015 17:03:47 GMT
http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.scala
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.scala b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.scala
new file mode 100644
index 0000000..3d8d929
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/SettingsPanel.scala
@@ -0,0 +1,646 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.clerezza.platform.accountcontrolpanel
+
+import java.io.ByteArrayInputStream
+import java.io.IOException
+import java.io.InputStream
+import java.io.UnsupportedEncodingException
+import java.net.URL
+import java.security.AccessControlException
+import java.security.AccessController
+import java.security.MessageDigest
+import java.security.NoSuchAlgorithmException
+import java.security.PrivilegedAction
+import java.util.Dictionary
+import java.util.HashMap
+import java.util.HashSet
+import java.util.Hashtable
+import java.util.Iterator
+import java.util.Map
+import java.util.Set
+import javax.ws.rs.Consumes
+import javax.ws.rs.FormParam
+import javax.ws.rs.GET
+import javax.ws.rs.POST
+import javax.ws.rs.Path
+import javax.ws.rs.PathParam
+import javax.ws.rs.QueryParam
+import javax.ws.rs.WebApplicationException
+import javax.ws.rs.core.Context
+import javax.ws.rs.core.MediaType
+import javax.ws.rs.core.Response
+import javax.ws.rs.core.Response.ResponseBuilder
+import javax.ws.rs.core.UriInfo
+import org.apache.felix.scr.annotations.Component
+import org.apache.felix.scr.annotations.Property
+import org.apache.felix.scr.annotations.Reference
+import org.apache.felix.scr.annotations.ReferenceCardinality
+import org.apache.felix.scr.annotations.ReferencePolicy
+import org.apache.felix.scr.annotations.Service
+import org.osgi.framework.Bundle
+import org.osgi.framework.BundleException
+import org.osgi.service.cm.Configuration
+import org.osgi.service.cm.ConfigurationAdmin
+import org.osgi.service.component.ComponentContext
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.apache.clerezza.jaxrs.utils.TrailingSlash
+import org.apache.clerezza.jaxrs.utils.RedirectUtil
+import org.apache.clerezza.jaxrs.utils.form.FormFile
+import org.apache.clerezza.jaxrs.utils.form.MultiPartBody
+import org.apache.clerezza.platform.accountcontrolpanel.ontologies.CONTROLPANEL
+import org.apache.clerezza.platform.config.SystemConfig
+import org.apache.clerezza.platform.graphprovider.content.ContentGraphProvider
+import org.apache.clerezza.platform.typerendering.RenderletManager
+import org.apache.clerezza.platform.typerendering.scala.PageRenderlet
+import org.apache.clerezza.platform.typerendering.scalaserverpages.ScalaServerPagesRenderlet
+import org.apache.clerezza.rdf.core.BNode
+import org.apache.clerezza.rdf.core.Graph
+import org.apache.clerezza.rdf.core.Literal
+import org.apache.clerezza.rdf.core.LiteralFactory
+import org.apache.clerezza.rdf.core.MGraph
+import org.apache.clerezza.rdf.core.NonLiteral
+import org.apache.clerezza.rdf.core.Triple
+import org.apache.clerezza.rdf.core.TypedLiteral
+import org.apache.clerezza.rdf.core.UriRef
+import org.apache.clerezza.rdf.core.impl.PlainLiteralImpl
+import org.apache.clerezza.rdf.core.impl.SimpleLiteralFactory
+import org.apache.clerezza.rdf.core.impl.SimpleMGraph
+import org.apache.clerezza.rdf.core.impl.TripleImpl
+import org.apache.clerezza.rdf.ontologies.OSGI
+import org.apache.clerezza.rdf.ontologies.PERMISSION
+import org.apache.clerezza.rdf.ontologies.PLATFORM
+import org.apache.clerezza.rdf.ontologies.RDF
+import org.apache.clerezza.rdf.utils.GraphNode
+import org.apache.clerezza.rdf.utils.UnionMGraph
+
+object SettingPanel {
+  val logger: Logger = LoggerFactory.getLogger(classOf[SettingsPanel])
+}
+
+/**
+ *
+ * Account control panel
+ *
+ * @author mir, hasan
+ */
+@Path("/user/{id}/control-panel")
+class SettingsPanel {
+
+  import SettingPanel.logger
+
+  /**
+   * Mainpage
+   *
+   * @param id is the username as given in the URL
+   * @return an array of installed {@link Bundle}s to be managed
+   *
+   */
+  @GET
+  def settingsPage(@PathParam(value = "id") idP: String,
+              @QueryParam("changedPassword") changedPassword: String,
+              @Context uriInfo: UriInfo): GraphNode = {
+    TrailingSlash.enforceNotPresent(uriInfo)
+    val id: String = idP
+    var graphNode: GraphNode = null
+    AccessController.checkPermission(new AccountControlPanelAppPermission(id, ""))
+    try {
+      AccessController.checkPermission(new UserBundlePermission(id, ""))
+      graphNode = AccessController.doPrivileged(new PrivilegedAction[GraphNode] {
+        def run: GraphNode = {
+          var bundles: Array[Bundle] = userBundles(getAgent(id))
+          return asGraphNode(id, bundles)
+        }
+      })
+    }
+    catch {
+      case e: AccessControlException => {
+        graphNode = new GraphNode(new BNode, new SimpleMGraph)
+        graphNode.addProperty(CONTROLPANEL.userBundlePermission, LiteralFactory.getInstance.createTypedLiteral(false))
+      }
+    }
+    try {
+      AccessController.checkPermission(new ChangePasswordPermission(id, ""))
+      graphNode.addProperty(CONTROLPANEL.changePasswordPermission, LiteralFactory.getInstance.createTypedLiteral(true))
+    }
+    catch {
+      case e: AccessControlException => {
+        graphNode.addProperty(CONTROLPANEL.changePasswordPermission, LiteralFactory.getInstance.createTypedLiteral(false))
+      }
+    }
+    if (changedPassword != null && changedPassword.equals("false")) {
+      graphNode.addProperty(CONTROLPANEL.changedPassword, new PlainLiteralImpl("false"))
+    }
+    graphNode.addProperty(RDF.`type`, CONTROLPANEL.SettingsPage)
+    graphNode.addProperty(RDF.`type`, PLATFORM.HeadedPage)
+    return graphNode
+  }
+
+  private def addBundleDescriptionToGraph(responseGraph: MGraph, bundle: Bundle): Unit = {
+    var status: TypedLiteral = LiteralFactory.getInstance.createTypedLiteral(bundle.getState)
+    var bundleUri: UriRef = new UriRef(bundle.getLocation)
+    var triple: Triple = new TripleImpl(bundleUri, OSGI.status, status)
+    responseGraph.add(triple)
+    var bundleId: TypedLiteral = LiteralFactory.getInstance.createTypedLiteral(bundle.getBundleId)
+    triple = new TripleImpl(bundleUri, OSGI.bundle_id, bundleId)
+    responseGraph.add(triple)
+  }
+
+  private def asGraphNode(userId: String, bundles: Array[Bundle]): GraphNode = {
+    val responseGraph: MGraph = new SimpleMGraph
+    for (bundle <- bundles) {
+      addBundleDescriptionToGraph(responseGraph, bundle)
+    }
+    return AccessController.doPrivileged(new PrivilegedAction[GraphNode] {
+      def run: GraphNode = {
+        var userDescriptionGraph: Graph = new GraphNode(getAgent(userId), systemGraph).getNodeContext
+        var unionGraph: UnionMGraph = new UnionMGraph(responseGraph, userDescriptionGraph)
+        var graphNode: GraphNode = new GraphNode(getAgent(userId), unionGraph)
+        graphNode.addProperty(CONTROLPANEL.userBundlePermission, LiteralFactory.getInstance.createTypedLiteral(true))
+        return graphNode
+      }
+    })
+  }
+
+  /**
+   * Retrieves all bundles owned by a user represented by agent
+   *
+   * @param agent represents the user who owns bundles to be returned
+   * @return an array of {@link Bundle}s owned by the user
+   *
+   */
+  private def userBundles(agent: NonLiteral): Array[Bundle] = {
+    logger.debug("Retrieve all bundles from user: {}", agent)
+    var installedBundles: Array[Bundle] = componentContext.getBundleContext.getBundles
+    val locationMapper: Map[String, Long] = new HashMap[String, Long]
+    for (b <- installedBundles) {
+      locationMapper.put(b.getLocation, b.getBundleId)
+    }
+    return AccessController.doPrivileged(new PrivilegedAction[Array[Bundle]] {
+      def run: Array[Bundle] = {
+        var bundles: Set[Bundle] = new HashSet[Bundle]
+        var agentBundles: Iterator[Triple] = systemGraph.filter(null, OSGI.owner, agent)
+        while (agentBundles.hasNext) {
+          val location: String = (agentBundles.next.getSubject.asInstanceOf[UriRef]).getUnicodeString
+          try {
+            val id: Long = locationMapper.get(location)
+            bundles.add(componentContext.getBundleContext.getBundle(id))
+          } catch {
+            case _:NumberFormatException => None
+          }
+        }
+        return bundles.toArray(new Array[Bundle](bundles.size))
+      }
+    })
+  }
+
+  private def getAgent(id: String): NonLiteral = {
+    logger.debug("Get agent with id {}", id)
+    var agents: Iterator[Triple] = systemGraph.filter(null, PLATFORM.userName, new PlainLiteralImpl(id))
+    if (agents.hasNext) {
+      return agents.next.getSubject
+    }
+    else {
+      logger.debug("System graph does not contain user: {}", id)
+      var responseBuilder: Response.ResponseBuilder = Response.ok("<html><body>User does not exist</body></html>")
+      throw new WebApplicationException(responseBuilder.build)
+    }
+  }
+
+  private def getAgentPathPrefix(agent: NonLiteral): PlainLiteralImpl = {
+    return AccessController.doPrivileged(new PrivilegedAction[PlainLiteralImpl] {
+      def run: PlainLiteralImpl = {
+        var pathPrefixes: Iterator[Triple] = systemGraph.filter(agent, OSGI.agent_path_prefix, null)
+        if (pathPrefixes.hasNext) {
+          return pathPrefixes.next.getObject.asInstanceOf[PlainLiteralImpl]
+        }
+        return null
+      }
+    })
+  }
+
+  /**
+   * Installs a bundle from the specified location.
+   *
+   * @param id is the username as given in the URL
+   * @param location specifies the URL of the bundle to be installed
+   * @return an array of installed {@link Bundle}s to be managed
+   *
+   */
+  @POST
+  @Path("install-bundle")
+  @Consumes def installBundle(@PathParam(value = "id") id: String, multiForm: MultiPartBody, @Context uriInfo: UriInfo): Response = {
+    AccessController.checkPermission(new AccountControlPanelAppPermission(id, ""))
+    AccessController.checkPermission(new UserBundlePermission(id, ""))
+    var formFiles: Array[FormFile] = multiForm.getFormFileParameterValues("bundle")
+    var filename: String = formFiles(0).getFileName
+    var bundleBytes: Array[Byte] = formFiles(0).getContent
+    if (bundleBytes.length == 0) {
+      var message: String = null
+      if (filename.equals("")) {
+        message = "No bundle specified"
+      }
+      else {
+        message = "Bundle has length 0"
+      }
+      var responseBuilder: Response.ResponseBuilder = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(message)
+      throw new WebApplicationException(responseBuilder.build)
+    }
+    val bundleInputStream: InputStream = new ByteArrayInputStream(bundleBytes)
+    val location: String = "userbundle:" + id + "/" + filename
+    logger.info("Install bundle {} to location {}", id, location)
+    AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+      def run: Array[Bundle] = {
+        val agent: NonLiteral = getAgent(id)
+        val triple: Triple = new TripleImpl(new UriRef(location), OSGI.owner, agent)
+        try {
+          systemGraph.add(triple)
+          var bundle: Bundle = componentContext.getBundleContext.installBundle(location, bundleInputStream)
+          var prefix: PlainLiteralImpl = getAgentPathPrefix(agent)
+          if (prefix != null) {
+            addBundlePrefix(bundle, prefix.getLexicalForm)
+          }
+          return null
+        }
+        catch {
+          case ex: BundleException => {
+            systemGraph.remove(triple)
+            logger.debug("Failed to install a bundle from: {}", location)
+            logger.error("Exception during install bundle: {}", ex)
+            var responseBuilder: Response.ResponseBuilder = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(ex.getMessage)
+            throw new WebApplicationException(responseBuilder.build)
+          }
+        }
+      }
+    })
+    return RedirectUtil.createSeeOtherResponse("../control-panel", uriInfo)
+  }
+
+  private def addBundlePrefix(bundle: Bundle, prefix: String): Unit = {
+    var symbolicName: String = bundle.getSymbolicName
+    /*if (configAdmin != null) {
+      try {
+        var configuration: Configuration = configAdmin.getConfiguration(classOf[TriaxrsPrefixManager].getName)
+        val properties = configuration.getProperties match {
+          case null => new Hashtable[String, AnyRef]()
+          case dict: Dictionary[String, AnyRef] => dict
+        }
+        var mappings = TriaxrsPrefixManager.parseMappings(properties.get(TriaxrsPrefixManager.TRIAXRS_MAPPINGS).asInstanceOf[Array[String]])
+        logger.debug("Prefix {} added to bundle {}", prefix, symbolicName)
+        mappings.put(symbolicName, prefix)
+        var newMappings: Array[String] = TriaxrsPrefixManager.unparseMappings(mappings)
+        properties.put(TriaxrsPrefixManager.TRIAXRS_MAPPINGS, newMappings)
+        configuration.update(properties)
+      }
+      catch {
+        case e: IOException => {
+          logger.warn("Unable to update configuration: {}", e.toString)
+        }
+      }
+    }
+    else {
+      logger.warn("Cannot add prefix mapping. Configuration Admin is missing")
+    }*/
+  }
+
+  private[accountcontrolpanel] def removeBundlePrefix(bundle: Bundle): Unit = {
+    var symbolicName: String = bundle.getSymbolicName
+    /*if ((this.configAdmin != null) && (symbolicName != null)) {
+      try {
+        val configuration: Configuration = configAdmin.getConfiguration(classOf[TriaxrsPrefixManager].getName)
+        val properties = configuration.getProperties match {
+          case null => new Hashtable[String, AnyRef]()
+          case dict: Dictionary[String, AnyRef] => dict
+        }
+        val mappings = TriaxrsPrefixManager.parseMappings(properties.get(TriaxrsPrefixManager.TRIAXRS_MAPPINGS).asInstanceOf[Array[String]])
+        mappings.remove(symbolicName)
+        val newMappings: Array[String] = TriaxrsPrefixManager.unparseMappings(mappings)
+        properties.put(TriaxrsPrefixManager.TRIAXRS_MAPPINGS, newMappings)
+        configuration.update(properties)
+      }
+      catch {
+        case e: IOException => {
+          logger.warn("Unable to update configuration: {}", e.toString)
+        }
+      }
+    }
+    else {
+      logger.warn("Cannot add prefix mapping. Configuration Admin is missing")
+    }*/
+  }
+
+  /**
+   * Starts the bundle with the specified bundle id.
+   *
+   * @param id is the username as given in the URL
+   * @param bundleIdString specifies the id of the bundle to be started
+   * @return an array of installed {@link Bundle}s to be managed
+   *
+   */
+  @POST
+  @Path("start-bundle")
+  def startBundle(@PathParam(value = "id") idP: String,
+             @FormParam("bundleId") bundleIdStringP: String,
+             @Context uriInfo: UriInfo): Response = {
+    val id: String = idP
+    val bundleIdString: String = bundleIdStringP
+    AccessController.checkPermission(new AccountControlPanelAppPermission(id, ""))
+    AccessController.checkPermission(new UserBundlePermission(id, ""))
+    logger.info("Start bundle {} ", id)
+    val bundleId: Long = bundleIdString.toLong
+    AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+      def run: Array[Bundle] = {
+        try {
+          val bundle: Bundle = componentContext.getBundleContext.getBundle(bundleId)
+          bundle.start
+        }
+        catch {
+          case e: BundleException => {
+            logger.debug("Failed to start bundle {}", bundleIdString)
+            logger.error("Exception during start bundle: {}", e)
+            var responseBuilder: Response.ResponseBuilder = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage)
+            throw new WebApplicationException(responseBuilder.build)
+          }
+        }
+        return null
+      }
+    })
+    return RedirectUtil.createSeeOtherResponse("../control-panel", uriInfo)
+  }
+
+  /**
+   * Stops the bundle with the specified bundle id.
+   *
+   * @param id is the username as given in the URL
+   * @param bundleIdString specifies the id of the bundle to be stopped
+   * @return an array of installed {@link Bundle}s to be managed
+   *
+   */
+  @POST
+  @Path("stop-bundle") def stopBundle(@PathParam(value = "id") idP: String,
+                          @FormParam("bundleId") bundleIdStringP: String,
+                          @Context uriInfo: UriInfo): Response = {
+    val id: String = idP
+    val bundleIdString: String = bundleIdStringP
+    AccessController.checkPermission(new AccountControlPanelAppPermission(id, ""))
+    AccessController.checkPermission(new UserBundlePermission(id, ""))
+    logger.info("Stop bundle {}", id)
+    val bundleId: Long = bundleIdString.toLong
+    AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+      def run: Array[Bundle] = {
+        try {
+          var bundle: Bundle = componentContext.getBundleContext.getBundle(bundleId)
+          bundle.stop
+        }
+        catch {
+          case e: BundleException => {
+            logger.debug("Failed to stop bundle ", bundleIdString)
+            logger.error("Exception during stop bundle: {}", e)
+            var responseBuilder: Response.ResponseBuilder = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage)
+            throw new WebApplicationException(responseBuilder.build)
+          }
+        }
+        return null
+      }
+    })
+    return RedirectUtil.createSeeOtherResponse("../control-panel", uriInfo)
+  }
+
+  /**
+   * Uninstalls the bundle with the specified bundle id.
+   *
+   * @param id is the username as given in the URL
+   * @param bundleIdString specifies the id of the bundle to be uninstalled
+   * @return an array of installed {@link Bundle}s to be managed
+   *
+   */
+  @POST
+  @Path("uninstall-bundle")
+  def uninstallBundle(@PathParam(value = "id") idP: String,
+                @FormParam("bundleId") bundleIdStringP: String,
+                @Context uriInfo: UriInfo): Response = {
+    val id: String = idP
+    val bundleIdString: String = bundleIdStringP
+    AccessController.checkPermission(new AccountControlPanelAppPermission(id, ""))
+    AccessController.checkPermission(new UserBundlePermission(id, ""))
+    logger.info("Uninstall bundle {}", id)
+    val bundleId: Long = bundleIdString.toLong
+    AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+      def run: Array[Bundle] = {
+        val agent: NonLiteral = getAgent(id)
+        try {
+          var bundle: Bundle = componentContext.getBundleContext.getBundle(bundleId)
+          bundle.uninstall
+          val triple: Triple = new TripleImpl(new UriRef(bundle.getLocation), OSGI.owner, agent)
+          systemGraph.remove(triple)
+          removeBundlePrefix(bundle)
+        }
+        catch {
+          case e: BundleException => {
+            logger.debug("Failed to uninstall bundle {}", bundleIdString)
+            logger.error("Exception during uninstall bundle: {}", e)
+            var responseBuilder: Response.ResponseBuilder = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage)
+            throw new WebApplicationException(responseBuilder.build)
+          }
+        }
+        return null
+      }
+    })
+    return RedirectUtil.createSeeOtherResponse("../control-panel", uriInfo)
+  }
+
+  /**
+   * changes the password of an user
+   *
+   * @param idP id is the username as given in the URL
+   * @param lang represents the user's new standard language.
+   * @return
+   */
+  @POST
+  @Path("change-language")
+  def changeUserLanguage(@PathParam(value = "id") idP: String,
+                  @FormParam("availablelanguages") lang: String,
+                  @Context uriInfo: UriInfo): Response = {
+    val id: String = idP
+    AccessController.checkPermission(new AccountControlPanelAppPermission(id, ""))
+    AccessController.doPrivileged(new PrivilegedAction[AnyRef] {
+      def run: AnyRef = {
+        var userNode: GraphNode = new GraphNode(getAgent(id), systemGraph)
+        userNode.deleteProperties(PLATFORM.preferredLangInISOCode)
+        userNode.addProperty(PLATFORM.preferredLangInISOCode, LiteralFactory.getInstance.createTypedLiteral(lang))
+        return null
+      }
+    })
+    return RedirectUtil.createSeeOtherResponse("../control-panel", uriInfo)
+  }
+
+  /**
+   * changes the password of an user
+   *
+   * @param idP id is the username as given in the URL
+   * @param oldPW the current user password
+   * @param newPW the new password
+   * @param confirmNewPW the new password
+   * @return
+   */
+  @POST
+  @Path("change-password")
+  def changePassword(@PathParam(value = "id") idP: String,
+               @FormParam("oldPW") oldPW: String,
+               @FormParam("newPW") newPW: String,
+               @FormParam("confirmNewPW") confirmNewPW: String,
+               @Context uriInfo: UriInfo): Response = {
+    val id: String = idP
+    AccessController.checkPermission(new AccountControlPanelAppPermission(id, ""))
+    AccessController.checkPermission(new ChangePasswordPermission(id, ""))
+    var changedPassword: Boolean = false
+    if (newPW.trim.equals(confirmNewPW.trim) && checkPWStrings(oldPW, newPW)) {
+      changedPassword = AccessController.doPrivileged(new PrivilegedAction[Boolean] {
+        private def getCurrentPassword(agent: NonLiteral): String = {
+          var currentPassword: String = null
+          var oldPWTriple: Iterator[Triple] = systemGraph.filter(agent, PERMISSION.passwordSha1, null)
+          if (oldPWTriple.hasNext) {
+            var currentPWLiteral: Literal = oldPWTriple.next.getObject.asInstanceOf[Literal]
+            currentPassword = currentPWLiteral.getLexicalForm
+          }
+          return currentPassword
+        }
+
+        def run: Boolean = {
+          val agent: NonLiteral = getAgent(id)
+          var encodedOlpPW: String = getEncodedPW(oldPW)
+          var currentPassword: String = getCurrentPassword(agent)
+          if ((currentPassword != null) && !currentPassword.equals(encodedOlpPW)) {
+            logger.info("Typed wrong current password!")
+            return false
+          }
+          else {
+            removeOldPwAndAddNewPW(agent, currentPassword, newPW)
+            return true
+          }
+        }
+
+        private def removeOldPwAndAddNewPW(agent: NonLiteral, currentPassword: String, newPW: String): Unit = {
+          var newPWTriple: Triple = new TripleImpl(agent, PERMISSION.passwordSha1, new PlainLiteralImpl(getEncodedPW(newPW)))
+          if (currentPassword != null) {
+            var oldPWTriple: Triple = new TripleImpl(agent, PERMISSION.passwordSha1, new PlainLiteralImpl(currentPassword))
+            systemGraph.remove(oldPWTriple)
+            logger.debug("removed old password from systemgraph")
+          }
+          systemGraph.add(newPWTriple)
+          logger.debug("user " + id + " changed password")
+        }
+
+        private def getEncodedPW(password: String): String = {
+          if (password == null) {
+            return null
+          }
+          try {
+            return bytes2HexString(MessageDigest.getInstance("SHA1").digest(password.getBytes("UTF-8")))
+          }
+          catch {
+            case e: NoSuchAlgorithmException => {
+              throw new RuntimeException(e)
+            }
+            case e: UnsupportedEncodingException => {
+              throw new RuntimeException(e)
+            }
+          }
+        }
+
+        private def bytes2HexString(bytes: Array[Byte]): String = {
+          val HEXDIGITS: Array[Char] = "0123456789abcdef".toCharArray
+          val result = new Array[Char](bytes.length << 1)
+          var j: Int = 0
+          for (i <- 0 to bytes.length - 1) {
+            result(j) = HEXDIGITS(bytes(i) >> 4 & 0xF)
+            result(j + 1) = HEXDIGITS(bytes(i) & 0xF)
+            j += 2
+          }
+          return new String(result)
+        }
+      })
+    }
+    else {
+      logger.info("Changing password failed!")
+      changedPassword = false
+    }
+    if (changedPassword) {
+      return RedirectUtil.createSeeOtherResponse("../control-panel", uriInfo)
+    }
+    else {
+      return RedirectUtil.createSeeOtherResponse("../control-panel?changedPassword=false", uriInfo)
+    }
+  }
+
+  /**
+   * checks if the typed strings are valid
+   */
+  private def checkPWStrings(oldPW: String, newPW: String): Boolean = {
+    if (newPW.length == 0) {
+      return false
+    }
+    return true
+  }
+
+  /**
+   * The activate method is called when SCR activates the component configuration.
+   *
+   * @param componentContext
+   */
+  protected def activate(componentContext: ComponentContext): Unit = {
+    this.componentContext = componentContext
+  }
+
+  protected def bindConfigurationAdmin(configAdmin: ConfigurationAdmin): Unit = {
+    logger.debug("Binding configuration admin")
+    this.configAdmin = configAdmin
+  }
+
+  protected def unbindConfigurationAdmin(configAdmin: ConfigurationAdmin): Unit = {
+    logger.debug("Unbinding configuration admin")
+    this.configAdmin = null
+  }
+
+  protected def bindSystemGraph(mgraph: MGraph): Unit = {
+    systemGraph = mgraph
+  }
+
+  protected def unbindSystemGraph(mgraph: MGraph): Unit = {
+    if (systemGraph == mgraph) {
+      systemGraph = null
+    }
+  }
+
+  protected def bindCgProvider(contentgraphprovider: ContentGraphProvider): Unit = {
+    cgProvider = contentgraphprovider
+  }
+
+  protected def unbindCgProvider(contentgraphprovider: ContentGraphProvider): Unit = {
+    if (cgProvider == contentgraphprovider) {
+      cgProvider = null
+    }
+  }
+
+  private var componentContext: ComponentContext = null
+  private var systemGraph: MGraph = null
+  private var cgProvider: ContentGraphProvider = null
+  private var configAdmin: ConfigurationAdmin = null
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/ContactConfirmRenderlet.scala
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/ContactConfirmRenderlet.scala b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/ContactConfirmRenderlet.scala
new file mode 100644
index 0000000..bb306aa
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/ContactConfirmRenderlet.scala
@@ -0,0 +1,109 @@
+package org.apache.clerezza.platform.accountcontrolpanel.html
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+import org.apache.clerezza.platform.accountcontrolpanel.ontologies.CONTROLPANEL
+import org.apache.clerezza.rdf.core._
+import org.apache.clerezza.rdf.scala.utils._
+import org.apache.clerezza.rdf.ontologies.FOAF
+import org.apache.clerezza.rdf.ontologies.RDF
+import org.apache.clerezza.rdf.scala.utils.Preamble._
+import org.apache.clerezza.platform.typerendering.scala._
+
+
+
+/**
+ * Metadata class for the person panel
+ */
+class ContactConfirmRenderlet extends SRenderlet {
+  def getRdfType() = CONTROLPANEL.ContactConfirmPage
+
+
+  override def renderedPage(arguments: XmlResult.Arguments) = new XmlPerson(arguments)
+
+  /**
+   * Content class for the Person Panel
+   */
+  class XmlPerson(args: XmlResult.Arguments) extends XmlResult(args) {
+
+    import RenderingUtility._
+    
+    //
+    // the content itself.
+    // This is the piece that is closest to a pure ssp, though there is still too much code in it
+    //
+
+    override def content = {
+      val primarySubject = res/FOAF.primaryTopic
+      <div id="tx-content">
+        {
+        if (primarySubject.hasProperty(RDF.`type`, FOAF.Person)) {
+          <form action="addContact" method="post">
+            {render(primarySubject, "box-naked")}
+            <input type="hidden" name="webId" value={primarySubject*} />
+            <input type="submit" value="Add this contact" />
+          </form>
+        } else {
+          <div>
+          <span>The resource {primarySubject!} of type {primarySubject/RDF.`type`} is not known to be a Person</span>
+          {
+            import collection.JavaConversions._
+            val otherPersons = (for (t <- primarySubject.getNodeContext.filter(null, RDF.`type`, FOAF.Person))
+              yield t.getSubject).toList
+            val personsWithUri: List[UriRef] = for (otherPerson <- otherPersons;
+                if otherPerson.isInstanceOf[UriRef]) yield otherPerson.asInstanceOf[UriRef]
+            if (personsWithUri.isEmpty) {
+              <span>No person could be found</span>
+            } else {
+              <div>
+                Maybe you want to add {
+                  if (personsWithUri.size > 1) {
+                    "one of the following "+personsWithUri.size+" persons:"
+                  } else {
+                    "the person"
+                  }
+                }
+                {
+                  for (otherPerson <- personsWithUri) yield {
+                    <form action="addContact" method="post">
+                      <span>{otherPerson}</span>
+                      {render(otherPerson, "box-naked")}
+                      <input type="hidden" name="webId" value={otherPerson.getUnicodeString} />
+                      <input type="submit" value="Add this contact" />
+                    </form>
+                  }
+                }
+              </div>
+            }
+          }
+          {
+            <form action="addContact" method="post">
+            You can add {primarySubject} as contact even though it does not seem to be a person.
+            <input type="hidden" name="webId" value={primarySubject*} />
+            <input type="submit" value="Add anyway" />
+          </form>
+          } </div>
+        }
+      }
+      <a href="../profile" onclick="history.go(-1)">Cancel</a>
+      </div>
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/PersonBox.scala
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/PersonBox.scala b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/PersonBox.scala
new file mode 100644
index 0000000..2b9913c
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/PersonBox.scala
@@ -0,0 +1,63 @@
+package org.apache.clerezza.platform.accountcontrolpanel.html
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+import org.apache.clerezza.platform.accountcontrolpanel.ontologies.CONTROLPANEL
+import org.apache.clerezza.rdf.core._
+import org.apache.clerezza.rdf.scala.utils._
+import org.apache.clerezza.rdf.ontologies.FOAF
+import org.apache.clerezza.rdf.scala.utils.Preamble._
+import org.apache.clerezza.platform.typerendering.scala._
+import scala.xml.Text
+
+
+
+/**
+ * Metadata class for the person panel
+ */
+class PersonBox extends SRenderlet {
+  def getRdfType() = FOAF.Person
+
+  override def getModePattern = "box-naked"
+
+  override def renderedPage(arguments: XmlResult.Arguments) = new XmlPerson(arguments)
+
+  /**
+   * Content class for the Person Panel
+   */
+  class XmlPerson(args: XmlResult.Arguments) extends XmlResult(args) {
+
+    import RenderingUtility._
+    
+    //
+    // the content itself.
+    // This is the piece that is closest to a pure ssp, though there is still too much code in it
+    //
+
+    override def content = {
+      val pixml= getAgentPix(res)
+      <div class="personInABox">
+        <table><tr><td>{pixml}</td></tr>
+        <tr><td>{new Text(getName(res))}</td></tr>
+        </table>
+      </div>
+    }
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/ProfilePanel.scala
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/ProfilePanel.scala b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/ProfilePanel.scala
new file mode 100644
index 0000000..7d65dff
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/ProfilePanel.scala
@@ -0,0 +1,295 @@
+package org.apache.clerezza.platform.accountcontrolpanel.html
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+import org.apache.clerezza.rdf.core._
+import org.apache.clerezza.rdf.scala.utils._
+import org.apache.clerezza.rdf.scala.utils.Preamble._
+import org.apache.clerezza.foafssl.ontologies.CERT
+import org.apache.clerezza.foafssl.ontologies.RSA
+import org.apache.clerezza.platform.typerendering.scala._
+import java.math.BigInteger
+import java.util.Date
+import java.text._
+import org.apache.clerezza.rdf.core.UriRef
+import org.apache.clerezza.platform.accountcontrolpanel.ontologies.CONTROLPANEL
+import org.apache.clerezza.rdf.ontologies.{RDFS, DC, FOAF}
+
+class ProfilePanel extends SRenderlet {
+
+  override def getRdfType() = CONTROLPANEL.ProfilePage
+
+  override def renderedPage(arguments: XmlResult.Arguments) = new ProfilePanelXHTML(arguments)
+
+  class ProfilePanelXHTML(arguments: XmlResult.Arguments) extends XmlResult(arguments ) {
+
+    //set header properties
+
+    resultDocModifier.addStyleSheet("/account-control-panel/style/profile.css");
+    resultDocModifier.addScriptReference("/account-control-panel/scripts/profile.js");
+    resultDocModifier.addScriptReference("/account-control-panel/scripts/IEKeygen.js");
+    resultDocModifier.setTitle("Account Control Panel");
+    resultDocModifier.addNodes2Elem("tx-module", <h1>Account Control Panel</h1>);
+    resultDocModifier.addNodes2Elem("tx-module-tabs-ol", <li class="tx-active"><a href="#">Profile</a></li>);
+    resultDocModifier.addNodes2Elem("tx-module-tabs-ol", <li><a href="control-panel">Settings</a></li>);
+
+    //constants and variables
+
+    lazy val agent: RichGraphNode = res / FOAF.primaryTopic
+
+
+    // the content itself
+    // clearly in this case there is so much more in the the methods, that one could hesitate to call this an ssp
+
+    override def content = {
+      <div id="tx-content">
+        <h2>Personal Profile</h2>{agent ! match {
+          case _: BNode => createWebId()
+          case _: UriRef => existingWebId()
+         }}
+      </div>
+
+    }
+
+    //methods used to create content
+
+    def cp(s: Any) =  new UriRef("http://clerezza.org/2009/03/controlpanel#" + s)
+    def platform(s: Any) = new UriRef("http://clerezza.org/2009/08/platform#" + s)
+
+
+    def createWebId() = {
+      <h3>Associate Profile to WebID</h3>
+      <div id="newOrExistingSelection">
+      <p>Your profile is not currently associated to a WebID. A WebID allows you
+        to link your friends as well as to log-in to many sites (supporting foaf+ssl
+        or open-id).
+      </p>
+      <p>You may either create a new WebID or associate your account to an
+        existing WebID. Only creating a WebID here will allow you to manage your
+        profile here.
+      </p>
+      <form action="#" id="associateSelection">
+        <button type="button" id="newWebIdButton">Create a new Web-Id</button>
+        <button type="button" id="existingWebIdButton">I already have a Web-ID and want to use it</button>
+      </form>
+      </div>
+      <div id="createNewWebId">
+      <p>You have chosen to create a new Web-Id.</p>
+      <p>The Web-ID will be created as follows:
+        <br/>
+        <ol>
+        <li>Web-Id:
+          {var webId = res / cp("suggestedPPDUri") *;
+          webId += "#me";
+          webId}
+        </li>
+        <li>Personal-Profile Document: {res/cp("suggestedPPDUri")*}</li>
+        </ol>
+      </p>
+      <form method="post" action="profile/create-new-web-id">
+        <input value="Create it!" type="submit"/>
+      </form>
+      </div>
+      <div id="setExistingWebId">
+      <p>Please enter your Web-Id, if your Web-Id supports Foaf+SSL you will
+        be able to use it to log in to this site.</p>
+      <form method="post" action="profile/set-existing-webid">
+        <label for="webid">WebID</label> <input type="text" name="webid" size="80" title="Web-ID"/>
+        <br/>
+        <input value="Associate Profile to Web-Id" type="submit"/>
+        <p/>
+      </form>
+      </div>
+
+    }
+
+    def existingWebId() = {
+      if ((res / cp("isLocalProfile")).as[Boolean]) {
+      existingLocalWebId()
+      } else {
+      roamingUser()
+      }
+    }
+
+
+    def existingLocalWebId() = {
+      <h3>Manage your profile</h3>
+       <p>Here you can change your public profile.</p>
+
+      <form method="post" action="profile/modify">
+      <input type="hidden" name="webId" value={agent *}/>
+      <table>
+        <tr><td class="formlabel">Name:</td>
+        <td><input type="text" name="name" value={agent / FOAF.name *}/></td>
+        </tr>
+        <tr><td class="formlabel multiline">Description:</td>
+        <td><textarea name="description" rows="3" cols="80">{agent / DC.description *}</textarea></td>
+        </tr>
+        <tr><td class="formlabel"><input value="Modify" type="submit"/></td><td/></tr>
+      </table>
+
+      <p/>
+      </form>
+
+      <h3>Contacts</h3>
+      
+      <table>{ var i =0
+        val friends = for (friend <- agent/FOAF.knows) yield {
+          <td><form method="post" action="profile/deleteContact">
+            {
+              friend! match {
+                case webId: UriRef => render(webId, "box-naked")
+                case _ => render(friend, "box-naked")
+              }
+            }
+            <br/>
+            <input type="hidden" name="contactWebId" value={friend*}/>
+            <input type="submit" value="remove contact" />
+          </form></td>
+        /*render(friend!.asInstanceOf[UriRef])
+              import PersonPanel._
+        <td class="personInABox">{personInABox(friend)}</td>*/
+       }
+       for (row <- friends.grouped(5)) yield <tr>{row}</tr>
+      }</table>
+      <form id="addContact" method="get" action="profile/addContact">
+      <label for="contactWebId">Add contact bei WebId:<br/></label>
+      <input type="text" name="contactWebId" size="80"/><input type="submit" value="add contact" />
+      </form>
+
+      <h3>Key and Certificate Creation</h3>
+
+      <script type="text/javascript"> <![CDATA[$(document).ready(  function() { configurePage(); }   ); ]]> </script>
+
+      <div id="iehelptext" style="display: none;">
+      <p>Using Internet Explorer under Windows Vista or above or Windows
+        Server 2008, you need to configure the following for this to work:</p>
+      <ul>
+        <li>Add this site to the <i>Trusted Sites</i> list: in Internet
+        Options -&gt; Security -&gt; Trusted Sites -&gt; Sites -&gt; Add ...</li>
+        <li>You may need to configure the trust level (in this tab), using
+        <i>Custom Level...</i>: enable <i>Initialize and script ActiveX
+          controls not marked as safe for scripting</i>.</li>
+        <li>If you are using Windows Vista without SP1 or above, you will
+        probably need to install <a href="cacert.crt">this certificate</a> as a
+        Trusted Root Certification Authority Certificate for your own
+        certificate installation to succeed. You should probably remove that
+        trusted root CA certificate afterwards.</li>
+      </ul>
+      </div>
+      <form id="keygenform" method="post" action="profile/keygen">
+      <input name="webId" id="webId" type="hidden" value={agent*} />
+      <table>
+        <colgroup><col width="1*"/><col/></colgroup>
+        <tr>
+        <td class="formlabel">Certificate Name:</td>
+        <td>
+          <input alt="create a certificate name that will help you distinguish it from others you may have" name="cn"
+              size="35" id="cn" type="text" value={ ((agent/FOAF.name*)+"@clerezza")}/>
+        </td>
+        </tr>
+        <tr>
+        <td class="formlabel">Key strength:</td>
+        <td id="keystrenghtd">
+          <keygen id="spkac" name="spkac" challenge="TheChallenge1"/>
+        </td>
+        </tr>
+        <tr>
+        <td class="formlabel">Valid for:</td>
+        <td>
+          <input type="text" name="days" value="365" size="4"/>
+          days <input type="text" name="hours" value="0.0" size="4"/> hours</td>
+        </tr>
+        <tr>
+        <td class="formlabel">Comment:</td>
+        <td><input type="text" name="comment" value="" size="80"/></td>
+        </tr>
+        <tr><td class="formlabel"><input id="keygensubmit" type="submit" value="create certificate" /></td><td/></tr>
+      </table>
+      </form>
+      <h3>Existing Certificates</h3>
+      <form method="post" action="profile/deletekey">
+      <table>
+        <tr><th>Delete</th><th>Certificate Details</th></tr>
+        <input name="webId" id="webId" type="hidden" value={agent*} />
+        <tbody>{
+          for (key <- agent/-CERT.identity )
+          yield { val modulus = (key/RSA.modulus).as[BigInteger]
+              if (modulus == null)  <span/> //todo: broken public key, should delete it
+              else <tr><td><input type="checkbox" name="keyhash" value={modulus.hashCode().toString()}/></td>
+            <td><table>
+              <tr><td class="propvalue">Created:</td><td>{beautifyDate(key/DC.date )}</td></tr>
+              <tr><td class="propvalue">Comment:</td><td>{ key/RDFS.comment* }</td></tr>
+              <tr><td class="propvalue multiline">Modulus:</td><td><code>{ beautifyHex(key/RSA.modulus) }</code></td></tr>
+              <tr><td class="propvalue">Exponent:</td><td><code>{ beautifyInt(key/RSA.public_exponent) }</code></td></tr>
+              </table>
+            </td>
+                </tr>}
+        }</tbody>
+      </table>
+      <input type="submit" value="Disable Keys"/>
+      </form>
+      <p></p>
+
+    }
+
+    def roamingUser() = {
+      <h3>Using remote profile</h3>
+       <p>
+      {agent / FOAF.nick *}, you have accessed this site using your WebID
+        {"<" + (agent *) + ">"}
+        which has not been
+        created on this site.To edit your profile you should visit the site issuing the
+        profile.</p>
+    }
+
+
+
+
+    def beautifyDate(dtIt: CollectedIter[RichGraphNode]) {
+      if (0 == dtIt.size) return "_"
+      DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.FULL).format(dtIt.as[Date])
+    }
+
+
+    def beautifyHex(dtIt: CollectedIter[RichGraphNode]): String = {
+      if (0 == dtIt.size) return "warning! missing. Key invalid"
+      //this is a problem, it should always be here or it is invalid, and key should be removed
+      val bigint: BigInteger = dtIt.as[BigInteger]
+      val bstr = bigint.toString(16).toUpperCase;
+      val sbuf = new StringBuffer(bstr.size + (bstr.size/2)+10)
+      var cnt = 0
+      for (c <- bstr.toCharArray) {
+      if ((cnt % 2) == 0) sbuf.append(' ')
+      sbuf.append(c)
+      cnt += 1
+      }
+      sbuf.toString
+    }
+
+
+
+    def beautifyInt(dtIt: CollectedIter[RichGraphNode] ) :String = {
+      if (0 == dtIt.size) return "warning! missing. Key invalid"
+      else return dtIt.as[BigInteger].toString
+    }
+  }
+}
+
+

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/RenderingUtility.scala
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/RenderingUtility.scala b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/RenderingUtility.scala
new file mode 100644
index 0000000..735aee0
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/RenderingUtility.scala
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.clerezza.platform.accountcontrolpanel.html
+
+
+import scala.xml.Node
+import scala.xml.NodeSeq
+import scala.xml.Text
+import java.net.URLEncoder
+import org.apache.clerezza._
+import org.apache.clerezza.rdf.core.UriRef
+import org.apache.clerezza.rdf.ontologies.FOAF
+import org.apache.clerezza.rdf.ontologies.RDFS
+import rdf.scala.utils.CollectedIter
+import rdf.scala.utils.RichGraphNode
+import rdf.scala.utils.Preamble._
+/**
+ * Some utility methods for the renderlets
+ */
+object RenderingUtility {
+  val emptyText = new Text("")
+
+  def ifE[T](arg:T)(template: T=>Node ):NodeSeq = {
+    def isEmpty(arg: Any): Boolean = {
+      arg match {
+        case prod: Product => prod.productIterator.forall(isEmpty(_))
+        case str: String => (str.size == 0)
+        case it: CollectedIter[RichGraphNode] => (it.size == 0)
+        case node: RichGraphNode => (null == node)
+        case other: AnyRef => (null == other)
+        case _ => false //literals can't be empty
+      }
+    }
+    if (isEmpty(arg)) return emptyText else template(arg)
+  }
+
+  def firstOf(node: RichGraphNode, uris: UriRef*):CollectedIter[RichGraphNode] = {
+    for (uri <- uris) {
+      val res : CollectedIter[RichGraphNode] = node/uri
+      if (res.size>0) return res
+    }
+    return new CollectedIter[RichGraphNode]()
+  }
+
+
+
+  /**
+   * Show a person: a picture, a link to their local profile and their name
+   * Different default icons should be shown if the agent is a person, company, group, robot...
+   *
+   * assumes the p is WebID node (can change later)
+   */
+  def getAgentPix(p: RichGraphNode) = {
+    val pix = firstOf(p, FOAF.depiction, FOAF.logo, FOAF.img).getNode match {
+      case uri: UriRef => uri.getUnicodeString
+      case _ => "http://upload.wikimedia.org/wikipedia/commons/0/0a/Gnome-stock_person.svg"
+    }
+    <a href={"/browse/person?uri="+encode(p*)}><img class="mugshot" src={pix}/></a>
+  }
+
+  private def encode(url: String): String =  URLEncoder.encode(url,"UTF8")
+
+  /**
+   * get a usable name from the properties available including nick
+   */
+  def getName(p: RichGraphNode): String =  {
+     val name = p/FOAF.name*;
+     if ("" != name ) { return name }
+     val firstNm: String = p/FOAF.firstName*;
+     val fmlyNm :String = firstOf(p, FOAF.family_name,FOAF.familyName)*;
+       if ("" != firstNm || "" != fmlyNm) { return firstNm+" "+fmlyNm }
+     return p*
+
+  }
+
+}
+

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/SettingsPanel.scala
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/SettingsPanel.scala b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/SettingsPanel.scala
new file mode 100644
index 0000000..a2a58e6
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/html/SettingsPanel.scala
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.clerezza.platform.accountcontrolpanel.html
+
+import org.apache.clerezza.rdf.scala.utils.Preamble._
+import org.apache.clerezza.platform.accountcontrolpanel.ontologies.CONTROLPANEL
+import org.apache.clerezza.platform.typerendering.scala._
+
+
+class SettingsPanel extends SRenderlet {
+
+  val getRdfType = CONTROLPANEL.SettingsPage
+
+    override def renderedPage(arguments: XmlResult.Arguments) = new XmlResult(arguments ) {
+    override def content = {
+import org.apache.clerezza.rdf.core.UriRef
+import scala.xml.NodeBuffer
+import scala.collection.mutable.ListBuffer
+def cp(s: Any) = new UriRef("http://clerezza.org/2009/03/controlpanel#"+s)
+def osgi(s: Any) = new UriRef("http://clerezza.org/2008/11/osgi#"+s)
+def platform(s: Any) = new UriRef("http://clerezza.org/2009/08/platform#" + s)
+val nodeBuff = new ListBuffer[NodeBuffer]
+resultDocModifier.setTitle("Account Control Panel");
+resultDocModifier.addNodes2Elem("tx-module", <h1>Account Control Panel</h1>);
+resultDocModifier.addNodes2Elem("tx-module-tabs-ol", <li><a href="profile">Profile</a></li>);
+resultDocModifier.addNodes2Elem("tx-module-tabs-ol", <li class="tx-active"><a href="#">Settings</a></li>);
+
+if ((res/cp("userBundlePermission")*) == "true") {
+  nodeBuff +=(<h2>Bundle Control Panel</h2>
+  <h3>Install Bundle</h3>
+
+  <form method="post" action="control-panel/install-bundle" enctype="multipart/form-data">
+    <input type="file" class="FieldText" name="bundle" size="30" title="bundle path"/><br/><br/>
+    <input style="width: 5em;" value="Install" type="submit"/><p />
+  </form>
+  <br/><br/>
+  <h3>User Bundles</h3>
+  <table border="1">
+  <tbody>
+    <tr>
+      <th>Location</th>
+      <th>Status</th>
+      <th colspan="4">Action</th>
+    </tr>
+
+    {for (renderlet <- (res/-osgi("owner")).sort((a,b) => ((a*)<(b*)))) yield
+    <tr>
+      <td>{renderlet*}</td>
+      <td>{renderlet/osgi("status")* match {
+        case "2" => "Installed"
+        case "4" => "Resolved"
+        case "8" => "Starting"
+        case "16" => "Stopping"
+        case "32" => "Active"
+        }}
+      </td>
+      {if (((renderlet/osgi("bundle_id")).length) > 0)
+      <td>
+      <form method="post" action="control-panel/start-bundle">
+      <input name="bundleId" value={(renderlet/osgi("bundle_id"))*} type="hidden"/>
+      <input value="start" type="submit"/>
+      </form>
+      </td>
+      <td>
+      <form method="post" action="control-panel/stop-bundle">
+      <input name="bundleId" value={(renderlet/osgi("bundle_id"))*} type="hidden"/>
+      <input value="stop" type="submit"/>
+      </form>
+      </td>
+      <td>
+      <form method="post" action="control-panel/uninstall-bundle">
+      <input name="bundleId" value={(renderlet/osgi("bundle_id"))*} type="hidden"/>
+      <input value="uninstall" type="submit"/>
+      </form>
+      </td>
+      else
+      <td colspan="3">Not registered as bundle</td>}
+      </tr>
+      }
+    </tbody>
+  </table>
+  <br/>)
+}
+
+if((res/cp("changePasswordPermission")*) == "true") {
+  nodeBuff +=(<h2>Change Password</h2>
+
+
+  <form action="control-panel/change-password" method="post">
+    <fieldset>
+      <ol style="display: block;">
+        <li class="tx-line" style="background-image: none;">
+          <label>Current Password:</label>
+          <span class="tx-item">
+            <input type="password" name="oldPW"/>
+          </span>
+        </li>
+        <li class="tx-line" style="background-image: none;">
+          <label>New Password:</label>
+          <span class="tx-item">
+            <input type="password" name="newPW"/>
+          </span>
+        </li>
+        <li class="tx-line" style="background-image: none;">
+          <label>Confirm new Password:</label>
+          <span class="tx-item">
+            <input type="password" name="confirmNewPW"/>
+          </span>
+        </li>
+        <br />
+        <input style="width: 5em;" type="submit" name="submit" value="Submit"/>
+      </ol>
+      <br/>
+    </fieldset>
+  </form>)
+
+
+}
+
+if((res/cp("changedPassword")).length > 0) {
+  nodeBuff +=(<br /><span>Password has not changed, either wrong current password or the
+        new password and the confirmation didn't match!<br /><br /></span>)
+}
+
+
+nodeBuff +=(<h2>Change user's default language</h2>
+  <form method="post" action="control-panel/change-language">
+    {render(context/platform("instance")/platform("languages"), "naked")}
+    <br/><br/>
+    <script type="text/javascript">$("#availablelanguages").val({"'" + (context/platform("user")/platform("preferredLangInISOCode")*) + "'"})</script>
+    <input style="width: 5em;" type="submit" name="submit" value="Submit"/>
+    <br/><br/>
+  </form>)
+
+<div id="tx-content">
+  <div class="tx-edit" style="margin-left: 0.5em;">
+  {if(nodeBuff.isEmpty)
+    <span>There are no settings you can configure for this account!</span>
+  else
+    nodeBuff
+  }
+  </div>
+</div>
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/permissions.scala
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/permissions.scala b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/permissions.scala
new file mode 100644
index 0000000..ae7953f
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/main/scala/org/apache/clerezza/platform/accountcontrolpanel/permissions.scala
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.clerezza.platform.accountcontrolpanel
+
+import java.security.Permission
+import org.slf4j.scala.Logging
+
+//note: file has lower class name, as it contains many classes
+
+
+/**
+ * superclass for the permission classes, to avoid a lot of boilerplate code
+ *
+ * @author bblfish, reto
+ */
+abstract
+class AbstractPermission(val accountName: String, val actions: String ="")
+  extends Permission(accountName) with Logging  {
+
+  if (actions != "") {
+    throw new RuntimeException(getClass.getName+": actions must be an empty String "+
+      "(second argument only in constructor for supporting building from canonical form")
+  }
+
+  def getActions: String = actions
+
+  /**
+   * A subclass implies another permission if and only if they are equals
+   */
+   override
+  def implies(permission: Permission): Boolean = {
+    logger.debug("checking for "+permission+" is implied by "+ this)
+    var result: Boolean = equals(permission)
+    return result
+  }
+
+  override
+  def equals(other: Any): Boolean =
+      other match {
+      case that:  AbstractPermission  =>  
+        (that eq this ) || ((this.getClass == that.getClass) && accountName == that.accountName )
+      case _ => false
+      }
+
+  /**
+   * For the hashCode the class and the accountName is considered
+   */
+  override
+  def hashCode: Int = {
+    return  getClass.hashCode + (if (accountName != null) accountName.hashCode else 0)
+  }
+}
+
+/**
+ * Permission to change the password
+ * @author ali
+ *
+ */
+class ChangePasswordPermission(accountName: String, actions: String ="")
+  extends AbstractPermission(accountName, actions) {
+
+}
+
+/**
+ * Permission to access the account control panel
+ *
+ * @author ali
+ *
+ */
+class AccountControlPanelAppPermission(accountName: String, actions: String ="")
+  extends AbstractPermission(accountName)  {
+
+
+}
+
+/**
+ * Permission for user to have own bundles
+ *
+ * @author mir
+ *
+ */
+class UserBundlePermission( accountName: String, actions: String ="")
+  extends AbstractPermission(accountName)  {
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/resources/documentation/style/style.css
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/resources/documentation/style/style.css b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/resources/documentation/style/style.css
new file mode 100644
index 0000000..ff49a4d
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/resources/documentation/style/style.css
@@ -0,0 +1,421 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+*/
+
+/*---------------------------------------------------------------------------
+ *  Two- and three-column layout
+ */
+
+#banner {
+    top: 0px;
+    left: 0px;
+    right: 0px;
+    height: 116px;
+}
+
+#left {
+    position: absolute;
+    z-index: 2;
+    left: 8px;
+    width: 184px;
+    top: 125px;
+    bottom: 8px;
+    margin: 0px;
+    padding: 0px;
+}
+
+#right {
+    position: absolute;
+    z-index: 1;
+    right: 8px;
+    width: 184px;
+    top: 125px;
+    bottom: 8px;
+    margin: 0px;
+    padding: 0px;
+}
+
+.Content3Column {
+    position: absolute;
+    top: 125px;
+    bottom: 8px;
+    left: 208px;
+    right: 216px;
+}
+
+.Content2Column {
+    position: absolute;
+    top: 125px;
+    bottom: 8px;
+    left: 208px;
+    right: 16px;
+}
+
+#center {
+    z-index: 3;
+    margin: 0px;
+    border: none;
+    padding-bottom: 8px;
+}
+
+
+/*---------------------------------------------------------------------------
+ *  Default element styles
+ */
+
+body {
+    padding: 0px;
+    margin: 0px;
+    border: 0px;
+
+    font-family: helvetica, arial, sans-serif;
+    font-size: 12px;
+
+    background-color: white;
+    color: black;
+}
+
+h1, h2, h3, h4, h5, h6 {
+    margin: 0px;
+    border: 0px;
+    padding: 0px;
+    font-weight: normal;
+}
+
+a:link { color: #008DA8; }
+a:active { color: #FE5400; }
+a:hover { color: #FE5400; }
+a:visited { color: black; }
+
+iframe {
+    width:100%;
+    height: 800px;
+    border: 0px;
+}
+
+img {
+    border: 0px;
+    padding: 0px;
+    margin: 0px;
+}
+
+p {
+    border: 0px;
+    padding: 0px;
+    margin: 0px;
+    margin-bottom: 10px;
+}
+
+blockquote {
+    margin-bottom: 10px;
+}
+
+td {
+    font-size: 12px;
+    padding: 2px;
+}
+
+tr.a {
+    background-color:  #e0e0e0;
+}
+tr.b {
+    background-color: #ffffff;
+}
+
+th {
+    font-size: 12px;
+    font-weight: bold;
+    white-space: nowrap;
+    padding: 2px;
+}
+
+th.Row {
+    text-align: left;
+    vertical-align: top;
+}
+
+ul, ol {
+    border: 0px;
+    padding: 0px;
+    margin-top: 0px;
+    margin-bottom: 12px;
+    margin-left: 20px;
+}
+
+
+/*---------------------------------------------------------------------------
+ *  Page banner
+ */
+
+#banner {
+    margin: 0px;
+    border: 0px;
+    border-bottom: 1px solid #008DA8;
+    padding: 0px;
+    background-color: #e0e0e0;
+    color: #008DA8;
+    vertical-align: bottom;
+}
+
+#banner a { text-decoration: none; }
+#banner a:visited { color: #008DA8; }
+#banner a:hover { color: #FE5400; }
+#banner a:active { color: #FE5400; }
+
+#logo {
+    position: absolute;
+    top: 5px;
+    left: 8px;
+}
+
+#versions {
+    position: absolute;
+    width: auto;
+    right: 0px;
+    top: 0px;
+    margin: 8px;
+    font-weight: normal;
+}
+
+/*---------------------------------------------------------------------------
+ *  Page content
+ */
+
+#content {
+    margin: 0px;
+    background-color: white;
+    color: black;
+    height: 100%;
+}
+
+#content h1 {
+    width: 100%;
+    font-size: 18px;
+    background-color: #008DA8;
+    color: white;
+    padding: 2px;
+    padding-left: 6px;
+    margin-top: 24px;
+    margin-bottom: 12px;
+}
+
+#content .FirstChild {  /* IE doesn't understand first-child pseudoelement */
+    margin-top: 0px;
+}
+
+#content a { text-decoration: underline; }
+#content a:link { color: #008DA8; }
+#content a:visited { color: #008DA8; }
+#content a:active { color: #FE5400; }
+#content a:hover { color: #FE5400; }
+
+#content h2 {
+    margin-top: 24px;
+    border-top: 1px solid #008DA8;
+    margin-bottom: 16px;
+    font-size: 15px;
+    font-weight: bold;
+    background-color:  #e0e0e0;;
+    padding: 2px;
+}
+
+#content li {
+    margin-bottom: 6px;
+}
+
+#content th {
+    background-color:  #e0e0e0;
+}
+
+#content td {
+    
+}
+
+.Source pre {
+    padding: 4px;
+    font-family: courier new, monospace;
+    font-size: 11px;
+    border: 1px solid #008DA8;
+    background-color:  #e0e0e0;
+    color: black;
+}
+
+.Source:before {
+    margin: 0px;
+    padding: 0px;
+    border: 0px;
+    font-size: inherit;
+    line-spacing: 100%;
+}
+
+.highlight {
+    background-color:  #e0e0e0;
+    border: 1px dotted #008DA8;
+    padding: 5px;
+}
+
+/* The following are for images, but can also apply to div's containing images. */
+
+#content .Float {
+    float: right;
+    margin-left: 8px;
+    margin-right: 0px;
+    margin-top: 8px;
+    margin-bottom: 8px;
+}
+
+#content .Diagram {
+    display: block;
+    margin-left: auto;
+    margin-right: auto;
+    margin-top: 8px;
+    margin-bottom: 8px;
+}
+
+
+#content .Inline {
+    display: inline;
+}
+
+.RuleOfThumb {
+    font-weight: bold;
+}
+
+/*---------------------------------------------------------------------------
+ *  Side panels
+ */
+
+.SidePanel {
+    background-color: white;
+    padding: 0px;
+    font-size: 11px;
+}
+
+.SidePanel h1 {
+    margin: 0px;
+    border: 0px;
+    padding: 4px;
+
+    color: #008DA8;
+
+    font-size: 12px;
+    font-weight: bold;
+}
+
+
+.SidePanel a { text-decoration: none; }
+.SidePanel a:link { color: #000000; }
+.SidePanel a:visited { color: #000000; }
+.SidePanel a:active { color: #FE5400; }
+.SidePanel a:hover { color: #FE5400; }
+
+/*---------------------------------------------------------------------------
+ *  Menus
+ */
+
+.MenuGroup {
+    border-left: 1px solid #A3DAE6;
+    border-top: 1px solid #A3DAE6;
+    border-bottom: 1px solid white; /* IE work-around */
+
+    margin-bottom: 8px;
+    background-color: white;
+    color: #008DA8;
+}
+
+.MenuGroup ul {
+    margin: 0px;
+    padding-left: 4px;
+    list-style-type: none;
+}
+
+.MenuGroup li {
+    padding: 2px;
+}
+
+.MenuGroup .currentLink {
+/*    background-color: #060;*/
+    background-color:  #e0e0e0;
+    color: #008DA8;
+}
+
+
+/*---------------------------------------------------------------------------
+ *  News panel
+ */
+
+.NewsGroup {
+    border-left: 1px solid #A3DAE6;
+    border-top: 1px solid #A3DAE6;
+    border-bottom: 1px solid white; /* IE workaround */
+    margin-bottom: 8px;
+
+    color: #008DA8;
+}
+
+.NewsItem {
+    margin: 4px;
+}
+
+.NewsDate {
+    font-weight: bold;
+    margin: 0px;
+    padding: 0px;
+}
+
+.NewsText {
+    padding: 0px;
+    margin: 0px;
+    margin-bottom: 8px;
+}
+
+.NewsText a { text-decoration: underline; }
+.NewsText a:link { color: #008DA8; }
+.NewsText a:visited { color: #008DA8; }
+.NewsText a:active { color: #FE5400; }
+.NewsText a:hover { color: #FE5400; }
+
+.NewsMore {
+    font-size: smaller;
+    margin: 4px;
+    margin-top: 8px;
+    text-align: left;
+}
+
+.NewsGroup td {
+    font-size: 12px;
+}
+
+/*---------------------------------------------------------------------------
+ *  Document meta-information
+ */
+
+.Meta {
+    margin-top: 64px;
+    font-size: smaller;
+    color: #008DA8;
+    text-align: right;
+}
+
+.Meta a { text-decoration: underline; }
+.Meta a:link { color: #008DA8; }
+.Meta a:visited { color: #008DA8; }
+.Meta a:active { color: #FE5400; }
+.Meta a:hover { color: #FE5400; }

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/resources/images/clerezza.png
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/resources/images/clerezza.png b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/resources/images/clerezza.png
new file mode 100644
index 0000000..cb0efb0
Binary files /dev/null and b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/resources/images/clerezza.png differ

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/site.xml
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/site.xml b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/site.xml
new file mode 100644
index 0000000..8d5a4cb
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/site.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+-->
+
+<project>
+    <body>
+        <menu name="Documentation">
+            <item name="Usage" href="documentation/usage.xhtml"/>
+        </menu>
+    </body>
+</project>

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/content/sitemap.xml
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/content/sitemap.xml b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/content/sitemap.xml
new file mode 100644
index 0000000..38be885
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/content/sitemap.xml
@@ -0,0 +1,28 @@
+<?xml version='1.0'?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you 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.
+
+-->
+
+<sitemap>
+    <section>
+        <name>Documentation</name>
+        <page>usage.xhtml</page>
+    </section>
+</sitemap>

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/content/usage.xhtml
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/content/usage.xhtml b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/content/usage.xhtml
new file mode 100644
index 0000000..6c22c93
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/content/usage.xhtml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us">
+	<head>
+		<title>Usage: How to use the Account Control Panel</title>
+	</head>
+	<body>
+		<h1>Usage: How to use the Account Control Panel</h1>
+		<p>Author: Tsuyoshi Ito - clerezza.org</p>
+		<p>Date: January 27, 2009</p>
+		<h2 id="list">1. List installed bundles</h2>
+		<p>
+			Each user can upload and install bundles into the platform. Users and permissions can be created via <a href="http://localhost:8282/admin/user-manager" target="_blank">http://localhost:8282/admin/user-manager</a> and <a href="http://localhost:8282/admin/role-manager" target="_blank">http://localhost:8282/admin/role-manager</a>. <br />
+			Enter the following URL: <a href="http://localhost:8282/user/admin/control-panel" target="_blank">http://localhost:8282/user/admin/control-panel</a> to list all bundles from the user "admin" (when asked to authenticate use username "admin" and password "admin). If you want to list installed bundles from another user, replace "admin" in the URL with the username of the other user.
+		</p>
+		<h2 id="install">2. Install a bundle</h2>
+		<p>
+            You can upload a bundle by clicking on the link <a href="http://localhost:8282/user/admin/control-panel/install-bundle-form">Install Bundle</a> on <a href="http://localhost:8282/user/admin/control-panel" target="_blank">http://localhost:8282/user/admin/control-panel</a>. Enter the URL of your bundle (e.g. Location: http://localhost/mybundle-1.0.jar) and click on the button "install". The uploaded and installed bundles have the same permission as you have. 
+        </p>
+		<h2 id="start">3. Start, Stop and Uninstall a bundle</h2>
+        <p>
+            A user can start, stop and  uninstall a bundle on <a href="http://localhost:8282/user/admin/control-panel" target="_blank">http://localhost:8282/user/admin/control-panel</a>, whereas "admin" can be replaced by another username. Click on the appropriate button for start , stop or uninstall a bundle.
+        </p>
+        <p>
+            That's all. Enjoy.
+        </p>
+    </body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/clerezza/blob/70220239/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/templates/skin.html
----------------------------------------------------------------------
diff --git a/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/templates/skin.html b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/templates/skin.html
new file mode 100644
index 0000000..4b10edb
--- /dev/null
+++ b/platform/accountcontrolpanel/platform.accountcontrolpanel.core/src/site/xsite/templates/skin.html
@@ -0,0 +1,71 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you 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.
+
+-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <title>clerezza.org - ${title}</title>
+        <link rel="stylesheet" type="text/css" href="style/style.css"/>
+        ${head}
+    </head>
+    <body>
+
+        <div id="banner">
+            <a href="http://clerezza.org/">
+              <img id="logo" src="../images/clerezza.png" alt="clerezza.org"/>
+            </a><br />
+        </div>
+
+        <div id="center" class="${centerClass}">
+            <div id="content">
+                <!-- <h1 class="FirstChild">${title}</h1> -->
+                ${body}
+                <p>Copyright (c) 2008 trialox.org (trialox AG, Switzerland)</p>
+                <br /><br />
+            </div>
+        </div>
+
+        <div class="SidePanel" id="left">
+            <#list sitemap.sections as section>
+                <div class="MenuGroup">
+                    <h1>${section.name}</h1>
+                    <ul>
+                        <#list section.entries as entry>
+                            <#if entry = page>
+                                <li class="currentLink">${entry.title}</li>
+                            <#else>
+                                <li><a href="${entry.href}">${entry.title}</a></li>
+                            </#if>
+                        </#list>
+                    </ul>
+                </div>
+            </#list>
+            <div class="MenuGroup">
+                  <h1>Project Site</h1>
+                  <ul>
+
+                              <li><a href="../index.html">Back to project site</a></li>
+                  </ul>
+              </div>
+        </div>
+
+  </body>
+</html>


Mime
View raw message