You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2007/12/04 12:40:28 UTC

svn commit: r600895 - in /incubator/sling/whiteboard/jcrinstall: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/sling/ src/main/java/org/apache/sling/jcr/ src/main/java/org/apache/sling/jcr/jcrins...

Author: fmeschbe
Date: Tue Dec  4 03:40:24 2007
New Revision: 600895

URL: http://svn.apache.org/viewvc?rev=600895&view=rev
Log:
Add JcrInstall tool inspired by Peter Kriens' FileInstall

Added:
    incubator/sling/whiteboard/jcrinstall/   (with props)
    incubator/sling/whiteboard/jcrinstall/pom.xml   (with props)
    incubator/sling/whiteboard/jcrinstall/src/
    incubator/sling/whiteboard/jcrinstall/src/main/
    incubator/sling/whiteboard/jcrinstall/src/main/java/
    incubator/sling/whiteboard/jcrinstall/src/main/java/org/
    incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/
    incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/sling/
    incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/sling/jcr/
    incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/
    incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/JcrInstall.java   (with props)
    incubator/sling/whiteboard/jcrinstall/src/main/resources/
    incubator/sling/whiteboard/jcrinstall/src/main/resources/OSGI-INF/
    incubator/sling/whiteboard/jcrinstall/src/main/resources/OSGI-INF/metatype/
    incubator/sling/whiteboard/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties   (with props)

Propchange: incubator/sling/whiteboard/jcrinstall/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Dec  4 03:40:24 2007
@@ -0,0 +1,3 @@
+.classpath
+.project
+target

Added: incubator/sling/whiteboard/jcrinstall/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrinstall/pom.xml?rev=600895&view=auto
==============================================================================
--- incubator/sling/whiteboard/jcrinstall/pom.xml (added)
+++ incubator/sling/whiteboard/jcrinstall/pom.xml Tue Dec  4 03:40:24 2007
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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 xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>1-incubator-SNAPSHOT</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.jcr.jcrinstall</artifactId>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Sling - JCR based Bundle and Configuration Management</name>
+    <description>
+        This bundle watches a repository location for files being added,
+        updated and removed. JAR files (extension ".jar") in this
+        location are installed and uninstalled when they are no longer
+        there. Updating the JAR file in the location will update the
+        bundle. Configuration files (extension ".cfg") in this location
+        create configurations and delete configurations when they are no
+        longer there. Updating the configuration file in the location
+        will update the configuration.
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/whiteboard/jcrinstall
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/whiteboard/jcrinstall
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrinstall
+        </url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Private-Package>
+                            org.apache.sling.jcr.jcrinstall
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi_R4_core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi_R4_compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

Propchange: incubator/sling/whiteboard/jcrinstall/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/JcrInstall.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/JcrInstall.java?rev=600895&view=auto
==============================================================================
--- incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/JcrInstall.java (added)
+++ incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/JcrInstall.java Tue Dec  4 03:40:24 2007
@@ -0,0 +1,554 @@
+/*
+ * 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.sling.jcr.jcrinstall;
+
+import static org.osgi.service.log.LogService.LOG_ERROR;
+import static org.osgi.service.log.LogService.LOG_INFO;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.ValueFormatException;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+import javax.jcr.observation.ObservationManager;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * This clever little bundle watches a directory and will install any jar file
+ * if finds in that directory (as long as it is a valid bundle and not a
+ * fragment).
+ *
+ * @scr.component label="%jcrinstall.name" description="%jcrinstall.description"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.property name="service.description" value="Sling Bundle Installer"
+ */
+public class JcrInstall implements EventListener {
+
+    /** @scr.property */
+    public static final String USER = "jcrinstall.user";
+
+    /** @scr.property */
+    public static final String PASSWORD = "jcrinstall.password";
+
+    /** @scr.property */
+    public static final String WORKSPACE = "jcrinstall.workspace";
+
+    /** @scr.property value="/system/install" */
+    public final static String DIR = "jcrinstall.dir";
+
+    private static final String ALIAS_KEY = "_alias_factory_pid";
+
+    /** The default location to watch for bundles/configurations to manage */
+    private static final String DEFAULT_DIR = "/system/install";
+
+    private static final String JCR_CONTENT = "jcr:content";
+
+    /** The relative path of the data of an nt:file node */
+    private static final String JCR_CONTENT_DATA = JCR_CONTENT + "/jcr:data";
+
+    /** The Bundle location prefix for bundles installed through JcrInstall */
+    private static final String JCR_INSTALL_PREFIX = "jcrinstall:";
+
+    /** @scr.reference */
+    private Repository repository;
+
+    /** @scr.reference */
+    private PackageAdmin padmin;
+
+    /** @scr.reference cardinality="0..1" policy="dynamic" */
+    private ConfigurationAdmin cmTracker;
+
+    /** @scr.reference cardinality="0..1" policy="dynamic" */
+    private LogService log;
+
+    private ComponentContext context;
+
+    private Session session;
+
+    protected void activate(ComponentContext context)
+            throws RepositoryException {
+        // System.out.println("FILEINSTALL | aQute (c) 2007 v1.3");
+        this.context = context;
+
+        // Created the initial configuration
+        Dictionary<?, ?>properties = context.getProperties();
+        String workspace = (String) properties.get(WORKSPACE);
+
+        String user = (String) properties.get(USER);
+        if (user == null || user.length() == 0) {
+            session = getRepository().login(workspace);
+        } else {
+            String pass = (String) properties.get(PASSWORD);
+            if (pass == null) {
+                pass = "";
+            }
+            SimpleCredentials creds = new SimpleCredentials(user,
+                pass.toCharArray());
+            session = getRepository().login(creds, workspace);
+        }
+
+        String dir  = (String) properties.get(DIR);
+        if (dir == null || dir.length() == 0) {
+            dir = DEFAULT_DIR;
+        } else if (dir.charAt(0) != '/') {
+            dir = "/" + dir;
+        }
+
+        ObservationManager om = session.getWorkspace().getObservationManager();
+        om.addEventListener(this, 255, dir, true, null,
+            new String[] { "nt:file", "nt:resource" }, false);
+    }
+
+    protected void deactivate(ComponentContext oldContext) {
+        if (session != null) {
+            try {
+                ObservationManager om = session.getWorkspace().getObservationManager();
+                om.removeEventListener(this);
+            } catch (RepositoryException re) {
+                log(LogService.LOG_ERROR, "Problem while closing watcher", re);
+            } finally {
+                // no matter what, close the session
+                session.logout();
+                session = null;
+            }
+        }
+
+        context = null;
+    }
+
+    //---------- EventListener interface --------------------------------------
+
+    public void onEvent(EventIterator events) {
+
+        Set<String> added = new HashSet<String>();
+        Set<String> updated = new HashSet<String>();
+        Set<String> removed = new HashSet<String>();
+
+        while (events.hasNext()) {
+            Event event = events.nextEvent();
+            try {
+                int type = event.getType();
+                String path = event.getPath();
+                if (path.endsWith(JCR_CONTENT)) {
+                    path = path.substring(0, path.length()
+                        - JCR_CONTENT.length() - 1);
+                    if (type == Event.NODE_ADDED) {
+                        if (removed.remove(path)) {
+                            updated.add(path);
+                        } else {
+                            added.add(path);
+                        }
+                    } else if (type == Event.NODE_REMOVED) {
+                        if (added.remove(path)) {
+                            updated.add(path);
+                        } else {
+                            removed.add(path);
+                        }
+                    }
+                } else if (path.endsWith(JCR_CONTENT_DATA)) {
+                    path = path.substring(0, path.indexOf(JCR_CONTENT_DATA) - 1);
+                    if (type == Event.PROPERTY_ADDED) {
+                        if (removed.remove(path)) {
+                            updated.add(path);
+                        } else {
+                            added.add(path);
+                        }
+                    } else if (type == Event.PROPERTY_CHANGED) {
+                        updated.add(path);
+                    } else if (type == Event.PROPERTY_REMOVED) {
+                        if (added.remove(path)) {
+                            updated.add(path);
+                        } else {
+                            removed.add(path);
+                        }
+                    }
+                }
+            } catch (RepositoryException re) {
+                log(LOG_ERROR, "Problem accessing event details", re);
+            }
+        }
+
+        try {
+            doBundles(added, updated, removed);
+            doConfigs(added, updated, removed);
+        } catch (Throwable t) {
+            log(LOG_ERROR, "Serious Problem handling bundles or configuration", t);
+        }
+
+        if (!added.isEmpty()) {
+            log(LOG_INFO, "Some added files ignored: " + added, null);
+        }
+        if (!updated.isEmpty()) {
+            log(LOG_INFO, "Some updated files ignored: " + updated, null);
+        }
+        if (!removed.isEmpty()) {
+            log(LOG_INFO, "Some removed files ignored: " + removed, null);
+        }
+    }
+
+    //---------- Configuration Management -------------------------------------
+
+    private void doConfigs(Set<String> added, Set<String> updated,
+            Set<String> removed) {
+
+        ConfigurationAdmin ca = getConfigurationAdmin();
+        if (ca == null) {
+            log(LOG_ERROR, "Configuration Admin missing, configurations do not work", null);
+            return;
+        }
+
+        // new configurations
+        for (Iterator<String> ai=added.iterator(); ai.hasNext(); ) {
+            String fileNode = ai.next();
+            if (fileNode.endsWith(".cfg")) {
+                try {
+                    setConfig(ca, fileNode);
+                    ai.remove();
+                } catch (Exception ex) {
+                    Throwable cause = (ex.getCause() == null)
+                            ? ex
+                            : ex.getCause();
+                    log(LOG_ERROR, "Cannot install configuration from " + fileNode, cause);
+                }
+            }
+        }
+
+        // modified configurations
+        for (Iterator<String> ui=updated.iterator(); ui.hasNext(); ) {
+            String fileNode = ui.next();
+            if (fileNode.endsWith(".cfg")) {
+                try {
+                    setConfig(ca, fileNode);
+                    ui.remove();
+                } catch (Exception ex) {
+                    Throwable cause = (ex.getCause() == null)
+                            ? ex
+                            : ex.getCause();
+                    log(LOG_ERROR, "Cannot update configuration from " + fileNode, cause);
+                }
+            }
+        }
+
+        // removed configurations
+        for (Iterator<String> ri=removed.iterator(); ri.hasNext(); ) {
+            String fileNode = ri.next();
+            if (fileNode.endsWith(".cfg")) {
+                try {
+                    deleteConfig(ca, fileNode);
+                    ri.remove();
+                } catch (Exception ex) {
+                    Throwable cause = (ex.getCause() == null)
+                            ? ex
+                            : ex.getCause();
+                    log(LOG_ERROR, "Cannot remove configuration for " + fileNode, cause);
+                }
+            }
+        }
+    }
+
+    private boolean setConfig(ConfigurationAdmin cm, String fileNode) throws IOException, InvalidSyntaxException {
+        Properties p = new Properties();
+        InputStream in = null;
+        try {
+            in = getInputStream(fileNode);
+            p.load(in);
+        } catch (RepositoryException re) {
+            throw (IOException) new IOException("Cannot get stream to "
+                + fileNode).initCause(re);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException ioe) {
+                }
+            }
+        }
+
+        String pid[] = parsePid(fileNode);
+
+        // prepare configuration data
+        Hashtable<Object, Object> ht = new Hashtable<Object, Object>();
+        ht.putAll(p);
+        if (pid[1] != null) {
+            ht.put(ALIAS_KEY, pid[1]);
+        }
+
+        // get or create configuration
+        Configuration config = getConfiguration(cm, pid[0], pid[1]);
+        if (config.getBundleLocation() != null) {
+            config.setBundleLocation(null);
+        }
+
+        // set the configuration data
+        config.update(ht);
+
+        return true;
+    }
+
+    private boolean deleteConfig(ConfigurationAdmin cm, String fileNode)
+            throws IOException, InvalidSyntaxException {
+        String pid[] = parsePid(fileNode);
+        Configuration config = getConfiguration(cm, pid[0], pid[1]);
+        config.delete();
+        return true;
+    }
+
+    private String[] parsePid(String path) {
+        // cut off path and ".cfg" extension
+        int lastSlash = path.lastIndexOf('/');
+        String pid = path.substring(lastSlash + 1, path.length() - 4);
+
+        // split pid and factory pid alias
+        int n = pid.indexOf('-');
+        if (n > 0) {
+            // factory pid with config alias pid
+            String factoryPid = pid.substring(n + 1);
+            pid = pid.substring(0, n);
+            return new String[] { pid, factoryPid };
+        }
+
+        // only a simple pid
+        return new String[] { pid, null };
+    }
+
+    private Configuration getConfiguration(ConfigurationAdmin cm, String pid,
+            String factoryPid) throws IOException, InvalidSyntaxException {
+        if (factoryPid != null) {
+            Configuration configs[] = cm.listConfigurations("(|(" + ALIAS_KEY
+                + "=" + factoryPid + ")(.alias_factory_pid=" + factoryPid
+                + "))");
+            if (configs == null || configs.length == 0) {
+                return cm.createFactoryConfiguration(pid, null);
+            }
+
+            return configs[0];
+        }
+
+        return cm.getConfiguration(pid, null);
+    }
+
+    // ---------- Bundle management --------------------------------------------
+
+    private void doBundles(Set<String> added, Set<String> updated,
+            Set<String> removed) {
+        boolean refresh = false;
+
+        // update or uninstall bundles
+        Bundle bundles[] = getBundleContext().getBundles();
+        for (Bundle bundle : bundles) {
+            String location = bundle.getLocation();
+            if (!location.startsWith(JCR_INSTALL_PREFIX)) {
+                continue;
+            }
+
+            location = location.substring(JCR_INSTALL_PREFIX.length());
+            if (added.contains(location)) {
+                // not really !!
+            } else if (updated.remove(location)) {
+                // update bundle
+                refresh |= updateBundle(location, bundle);
+            } else if (removed.remove(location)) {
+                // remove bundle
+                refresh |= uninstallBundle(bundle);
+            }
+        }
+
+        for (Iterator<String> ai = added.iterator(); ai.hasNext();) {
+            String fileNode = ai.next();
+            if (fileNode.endsWith(".jar")) {
+                refresh |= installBundle(fileNode);
+                ai.remove();
+            }
+        }
+
+        if (refresh) {
+            refresh();
+        }
+    }
+
+    private boolean installBundle(String fileNode) {
+
+        InputStream ins = null;
+        try {
+            ins = getInputStream(fileNode);
+            String location = JCR_INSTALL_PREFIX + fileNode;
+            Bundle bundle = getBundleContext().installBundle(location, ins);
+
+            if (!isFragment(bundle)) {
+                try {
+                    bundle.start();
+                } catch (BundleException be) {
+                    log(LOG_ERROR, "Failed to start bundle " + bundle, be);
+                }
+            }
+
+            return true;
+
+        } catch (PathNotFoundException pnfe) {
+            // node or property not found
+            log(LOG_ERROR, "Missing file node or content at " + fileNode, pnfe);
+
+        } catch (ValueFormatException vfe) {
+            // cannot return property as a stream
+            log(LOG_ERROR, "Cannot access stream on file node " + fileNode, vfe);
+
+        } catch (RepositoryException re) {
+            // general Repository issue
+            log(LOG_ERROR, "Generic problem accessing file node " + fileNode, re);
+
+        } catch (BundleException be) {
+            // cannot install bundle
+            log(LOG_ERROR, "Failed to install bundle from " + fileNode, be);
+
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ioe) {
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private boolean updateBundle(String fileNode, Bundle bundle) {
+
+        InputStream ins = null;
+        try {
+            ins = getInputStream(fileNode);
+            bundle.update(ins);
+
+            return true;
+
+        } catch (PathNotFoundException pnfe) {
+            // node or property not found
+            log(LOG_ERROR, "Missing file node or content at " + fileNode, pnfe);
+
+        } catch (ValueFormatException vfe) {
+            // cannot return property as a stream
+            log(LOG_ERROR, "Cannot access stream on file node " + fileNode, vfe);
+
+        } catch (RepositoryException re) {
+            // general Repository issue
+            log(LOG_ERROR, "Generic problem accessing file node " + fileNode, re);
+
+        } catch (BundleException be) {
+            // cannot install bundle
+            log(LOG_ERROR, "Failed to update bundle from " + fileNode, be);
+
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ioe) {
+                }
+            }
+        }
+
+        return false;
+    }
+
+    private boolean uninstallBundle(Bundle bundle) {
+        try {
+            bundle.uninstall();
+            log(LOG_INFO, "Uninstalled " + bundle.getLocation(), null);
+            return true;
+        } catch (Exception e) {
+            log(LOG_ERROR, "failed to uninstall bundle: ", e);
+            return false;
+        }
+    }
+
+    private boolean isFragment(Bundle bundle) {
+        PackageAdmin padmin = getPackageAdmin();
+        return padmin.getBundleType(bundle) == PackageAdmin.BUNDLE_TYPE_FRAGMENT;
+    }
+
+    private void refresh() {
+        getPackageAdmin().refreshPackages(null);
+    }
+
+    // ---------- General Helper -----------------------------------------------
+
+    void log(int level, String message, Throwable t) {
+        LogService logger = log;
+        if (logger != null) {
+            logger.log(level, message, t);
+        } else {
+            PrintStream out = (level == LogService.LOG_ERROR)
+                    ? System.err
+                    : System.out;
+            out.println(message);
+            if (t != null) {
+                t.printStackTrace(out);
+            }
+        }
+    }
+
+    private InputStream getInputStream(String fileNode)
+            throws PathNotFoundException, ValueFormatException,
+            RepositoryException {
+        Node node = (Node) session.getItem(fileNode);
+        Property prop = node.getProperty(JCR_CONTENT_DATA);
+        return prop.getStream();
+    }
+
+    private BundleContext getBundleContext() {
+        return context.getBundleContext();
+    }
+
+    private PackageAdmin getPackageAdmin() {
+        return padmin;
+    }
+
+    private ConfigurationAdmin getConfigurationAdmin() {
+        return cmTracker;
+    }
+
+    private Repository getRepository() {
+        return repository;
+    }
+
+}
\ No newline at end of file

Propchange: incubator/sling/whiteboard/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/JcrInstall.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/whiteboard/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=600895&view=auto
==============================================================================
--- incubator/sling/whiteboard/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties (added)
+++ incubator/sling/whiteboard/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties Tue Dec  4 03:40:24 2007
@@ -0,0 +1,46 @@
+#
+#  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.
+#
+
+
+#
+# This file contains localization strings for configuration labels and
+# descriptions as used in the metatype.xml descriptor generated by the
+# the Sling SCR plugin
+
+jcrinstall.name.name = JCRInstall
+jcrinstall.description = This bundle watches a repository location for files \
+ being added, updated and removed. JAR files (extension ".jar") in this \
+ location are installed and uninstalled when they are no longer there. \
+ Updating the JAR file in the location will update the bundle. Configuration \
+ files (extension ".cfg") in this location create configurations and delete \
+ configurations when they are no longer there. Updating the configuration file \
+ in the location will update the configuration. 
+
+jcrinstall.user.name = User
+jcrinstall.user.description = The user name to log into the repository.
+jcrinstall.password.name = Password
+jcrinstall.password.description = The password to log into the repository 
+jcrinstall.workspace.name = Workspace
+jcrinstall.workspace.description = The name of the workspace containing the \
+ location where bundles and configurations to manage are expected.
+
+jcrinstall.dir.name = Location
+jcrinstall.dir.description = The absolute path of the repository location \
+ where bundles and configuration files will be placed. If this is empty or \
+ missing, the default location "/system/install" is used.
\ No newline at end of file

Propchange: incubator/sling/whiteboard/jcrinstall/src/main/resources/OSGI-INF/metatype/metatype.properties
------------------------------------------------------------------------------
    svn:eol-style = native