org.argeo.slc.demo.basic,\
org.argeo.slc.demo.minimal,\
-org.argeo.security.ui.initialPerspective=org.argeo.slc.client.ui.dist.anonymousDistributionPerspective
+#org.argeo.security.ui.initialPerspective=org.argeo.slc.client.ui.dist.anonymousDistributionPerspective
+org.argeo.security.ui.initialPerspective=org.argeo.slc.client.ui.dist.distributionPerspective
#org.argeo.security.ui.initialPerspective=org.argeo.security.ui.userHomePerspective
#org.argeo.security.ui.saveAndRestore=true
argeo.server.tomcat.config=conf/default-server-ssl.xml
# override ports to run the demo as a server
-#argeo.server.port.http=9070
-#argeo.server.port.https=9073
-#argeo.server.port.ajp=9079
-#argeo.ldap.port=19389
+argeo.server.port.http=9070
+argeo.server.port.https=9073
+argeo.server.port.ajp=9079
+argeo.ldap.port=19389
# anonymous url: http://localhost:7070/ui/public
# authenticated url: http://localhost:7070/ui/node
<property name="workspace" value="*" />\r
</bean>\r
\r
-\r
</beans>
\ No newline at end of file
<property name="proxyWorkspace" value="${slc.repo.jcr.proxyWorkspace}" />
<property name="defaultRepositories" ref="defaultRpmRepositories" />
</bean>
+
+ <!-- Draft to centralize multirepository connection process in an Argeo
+ environment -->
+ <!-- <bean id="repoService" class="org.argeo.slc.repo.core.RepoServiceImpl"
+ init-method="init" destroy-method="destroy"> <property name="repositoryFactory"
+ ref="repositoryFactory" /> <property name="keyring" ref="keyring" /> <property
+ name="nodeRepository" ref="nodeRepository" /> </bean> -->
</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <!-- RAP Specific open JCR file service -->
+ <bean id="openJcrFileService" class="org.argeo.slc.client.rap.OpenJcrFileService"
+ scope="prototype" init-method="init" destroy-method="destroy">
+ <property name="repoService" ref="repoService" />
+ </bean>
+
+ <bean id="org.argeo.slc.client.rap.openJcrFile" class="org.argeo.slc.client.ui.specific.OpenJcrFile"
+ scope="prototype">
+ <property name="repoService" ref="repoService" />
+ <!-- Workaround to only force instantiation -->
+ <property name="openJcrFileService" ref="openJcrFileService" />
+ </bean>
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
+
+ <bean id="repoService" class="org.argeo.slc.repo.core.RepoServiceImpl">
+ <property name="repositoryFactory" ref="repositoryFactory" />
+ <property name="keyring" ref="keyring" />
+ <property name="nodeRepository" ref="nodeRepository" />
+ </bean>
+
+</beans>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+ xmlns:osgi="http://www.springframework.org/schema/osgi"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi \r
+ http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+ http://www.springframework.org/schema/beans \r
+ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"\r
+ osgi:default-timeout="30000">\r
+\r
+ <beans:description>SLC UI RAP</beans:description>\r
+\r
+ <reference id="nodeRepository" interface="javax.jcr.Repository"\r
+ filter="(argeo.jcr.repository.alias=node)" />\r
+\r
+ <reference id="repositoryFactory" interface="javax.jcr.RepositoryFactory" />\r
+ <reference id="keyring" interface="org.argeo.security.crypto.CryptoKeyring" />\r
+\r
+</beans:beans>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>\r
-<?eclipse version="3.4"?>\r
+<?eclipse version="3.6"?>\r
<plugin>\r
-\r
- <extension\r
- point="org.eclipse.rap.ui.entrypoint">\r
- <entrypoint\r
- class="org.argeo.slc.client.rap.SlcSecureRap"\r
- parameter="slc"\r
- id="org.argeo.slc.client.rap.slcSecureRap">\r
- </entrypoint>\r
- </extension>\r
- \r
+ <extension\r
+ point="org.eclipse.rap.ui.entrypoint">\r
+ <entrypoint\r
+ id="org.argeo.slc.client.rap.slcSecureRap"\r
+ class="org.argeo.slc.client.rap.SlcSecureRap"\r
+ parameter="slc">\r
+ </entrypoint>\r
+ </extension>\r
+ \r
+ <!-- COMMANDS --> \r
+ <extension\r
+ point="org.eclipse.ui.commands">\r
+ <command\r
+ id="org.argeo.slc.client.rap.openJcrFile"\r
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"\r
+ name="Open Workspace Editor">\r
+ <commandParameter\r
+ id="param.repoNodePath"\r
+ name="Repo node path">\r
+ </commandParameter>\r
+ <commandParameter\r
+ id="param.repoUri"\r
+ name="Repo URI">\r
+ </commandParameter>\r
+ <commandParameter\r
+ id="param.workspaceName"\r
+ name="Workspace name">\r
+ </commandParameter>\r
+ <commandParameter\r
+ id="param.filePath"\r
+ name="File Path">\r
+ </commandParameter>\r
+ </command>\r
+ </extension>\r
</plugin>\r
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
+ <Bundle-Activator>org.argeo.slc.client.rap.SlcRapPlugin</Bundle-Activator>
<Require-Bundle>org.eclipse.rap.ui;resolution:=optional</Require-Bundle>
<Import-Package>
- *,
+ javax.jcr.nodetype,
javax.servlet,
- javax.servlet.http
+ javax.servlet.http,
+ org.argeo.eclipse.spring,
+ org.argeo.slc.repo.core,
+ *
</Import-Package>
</instructions>
</configuration>
</plugins>
</build>
<dependencies>
-
<!-- SLC -->
<dependency>
<groupId>org.argeo.slc</groupId>
- <artifactId>org.argeo.slc.client.ui</artifactId>
+ <artifactId>org.argeo.slc.repo</artifactId>
<version>1.1.17-SNAPSHOT</version>
</dependency>
--- /dev/null
+package org.argeo.slc.client.rap;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.repo.RepoService;
+import org.eclipse.rwt.RWT;
+import org.eclipse.rwt.service.IServiceHandler;
+import org.eclipse.rwt.service.IServiceManager;
+
+/**
+ * Basic Default service handler that retrieves and launch download of a file
+ * stored in a JCR Repository
+ */
+public class OpenJcrFileService implements IServiceHandler {
+
+ public final static String ID = SlcRapPlugin.PLUGIN_ID + ".openJcrFileService";
+
+ // use local node repo and repository factory to retrieve and log to
+ // relevant repository
+ public final static String PARAM_REPO_NODE_PATH = "param.repoNodePath";
+ // use URI and repository factory to retrieve and ANONYMOUSLY log in
+ // relevant repository
+ public final static String PARAM_REPO_URI = "param.repoUri";
+ public final static String PARAM_WORKSPACE_NAME = "param.workspaceName";
+ public final static String PARAM_FILE_PATH = "param.filePath";
+
+ public final static String SCHEME_HOST_SEPARATOR = "://";
+
+ /* DEPENDENCY INJECTION */
+ private RepoService repoService;
+
+ public OpenJcrFileService() {
+ }
+
+ public void init() {
+ IServiceManager manager = RWT.getServiceManager();
+ manager.registerServiceHandler(ID, this);
+ }
+
+ public void destroy() {
+ IServiceManager manager = RWT.getServiceManager();
+ manager.unregisterServiceHandler(ID);
+ }
+
+ public void service() throws IOException, ServletException {
+ String repoNodePath = RWT.getRequest().getParameter(PARAM_REPO_NODE_PATH);
+ String repoUri = RWT.getRequest().getParameter(PARAM_REPO_URI);
+ String wkspName = RWT.getRequest().getParameter(PARAM_WORKSPACE_NAME);
+ String filePath = RWT.getRequest().getParameter(PARAM_FILE_PATH);
+
+ // Get the file content
+ byte[] download = getFileAsByteArray(repoNodePath, repoUri, wkspName,
+ filePath);
+
+ // Send the file in the response
+ HttpServletResponse response = RWT.getResponse();
+ response.setContentType("application/octet-stream");
+ response.setContentLength(download.length);
+ String contentDisposition = "attachment; filename=\""
+ + JcrUtils.lastPathElement(filePath) + "\"";
+ response.setHeader("Content-Disposition", contentDisposition);
+
+ try {
+ response.getOutputStream().write(download);
+ } catch (IOException ioe) {
+ throw new SlcException("Error while writing the file " + filePath
+ + " to the servlet response", ioe);
+ }
+ }
+
+ protected byte[] getFileAsByteArray(String repoNodePath, String repoUri,
+ String wkspName, String filePath) {
+ Session businessSession = null;
+ try {
+ businessSession = repoService.getRemoteSession(repoNodePath,
+ repoUri, wkspName);
+ Node result = businessSession.getNode(filePath);
+
+ boolean isValid = true;
+ Node child = null;
+ if (!result.isNodeType(NodeType.NT_FILE))
+ isValid = false;
+ else {
+ child = result.getNode(Property.JCR_CONTENT);
+ if (!(child.isNodeType(NodeType.NT_RESOURCE) || child
+ .hasProperty(Property.JCR_DATA)))
+ isValid = false;
+ }
+
+ if (!isValid)
+ return null;
+
+ byte[] ba = null;
+ InputStream fis = null;
+ try {
+ fis = (InputStream) child.getProperty(Property.JCR_DATA)
+ .getBinary().getStream();
+ ba = IOUtils.toByteArray(fis);
+ } catch (Exception e) {
+ throw new SlcException(
+ "Stream error while opening file " + filePath
+ + " from repo " + repoUri == null ? repoNodePath
+ : repoUri, e);
+ } finally {
+ IOUtils.closeQuietly(fis);
+ }
+ return ba;
+
+ } catch (RepositoryException e) {
+ throw new SlcException("Unexpected error while "
+ + "getting repoNode info for repoNode at path "
+ + repoNodePath, e);
+ } finally {
+ JcrUtils.logoutQuietly(businessSession);
+ }
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepoService(RepoService repoService) {
+ this.repoService = repoService;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.client.rap;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ *
+ * Enable life-cycle management of RAP specific services
+ */
+public class SlcRapPlugin extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.argeo.slc.client.rap"; //$NON-NLS-1$
+
+ // The shared instance
+ private static SlcRapPlugin plugin;
+
+ /**
+ * The constructor
+ */
+ public SlcRapPlugin() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static SlcRapPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns an image descriptor for the image file at the given plug-in
+ * relative path
+ *
+ * @param path
+ * the path
+ * @return the image descriptor
+ */
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.slc.client.ui.specific;
+
+import java.net.URL;
+
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.client.rap.OpenJcrFileService;
+import org.argeo.slc.client.rap.SlcRapPlugin;
+import org.argeo.slc.repo.RepoService;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.rwt.RWT;
+import org.eclipse.rwt.service.IServiceHandler;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Rap specific command handler to open a file retrieved from a distant JCR
+ * Repository. It forwards the request to the correct service after encoding
+ * file name and path in the request URI.
+ *
+ * This command and the corresponding service are specific for RAP version [1.3,
+ * 2)
+ */
+public class OpenJcrFile extends AbstractHandler {
+ private final static Log log = LogFactory.getLog(OpenJcrFile.class);
+
+ public final static String ID = SlcRapPlugin.PLUGIN_ID + ".openJcrFile";
+
+ public final static String PARAM_REPO_NODE_PATH = OpenJcrFileService.PARAM_REPO_NODE_PATH;
+ public final static String PARAM_REPO_URI = OpenJcrFileService.PARAM_REPO_URI;
+ public final static String PARAM_WORKSPACE_NAME = OpenJcrFileService.PARAM_WORKSPACE_NAME;
+ public final static String PARAM_FILE_PATH = OpenJcrFileService.PARAM_FILE_PATH;
+
+ private RepoService repoService;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ String repoNodePath = event.getParameter(PARAM_REPO_NODE_PATH);
+ String repoUri = event.getParameter(PARAM_REPO_URI);
+ String wkspName = event.getParameter(PARAM_WORKSPACE_NAME);
+ String filePath = event.getParameter(PARAM_FILE_PATH);
+
+ // TODO remove
+ Session session = repoService.getRemoteSession(repoNodePath, repoUri,
+ wkspName);
+ JcrUtils.logoutQuietly(session);
+
+ // TODO sanity check
+ if (filePath == null || "".equals(filePath.trim()))
+ return null;
+
+ try {
+ if (log.isDebugEnabled())
+ log.debug("URL : "
+ + createFullDownloadUrl(repoNodePath, repoUri,
+ wkspName, filePath));
+ // RWT.getResponse().sendRedirect(createFullDownloadUrl(repoNodePath,
+ // repoUri,
+ // wkspName, filePath));
+
+ URL url = new URL(createFullDownloadUrl(repoNodePath, repoUri,
+ wkspName, filePath));
+ PlatformUI.getWorkbench().getBrowserSupport()
+ .createBrowser("DownloadDialog").openURL(url);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ private String createFullDownloadUrl(String repoNodePath, String repoUri,
+ String wkspName, String filePath) {
+ StringBuilder url = new StringBuilder();
+ url.append(RWT.getRequest().getRequestURL());
+
+ StringBuilder params = new StringBuilder();
+ params.append("?");
+ params.append(IServiceHandler.REQUEST_PARAM).append("=");
+ params.append(OpenJcrFileService.ID);
+ if (repoNodePath != null)
+ params.append("&").append(OpenJcrFileService.PARAM_REPO_NODE_PATH)
+ .append("=").append(repoNodePath);
+
+ if (repoUri != null)
+ params.append("&").append(OpenJcrFileService.PARAM_REPO_URI)
+ .append("=").append(repoUri);
+
+ if (wkspName != null)
+ params.append("&").append(OpenJcrFileService.PARAM_WORKSPACE_NAME)
+ .append("=").append(wkspName);
+
+ if (filePath != null)
+ params.append("&").append(OpenJcrFileService.PARAM_FILE_PATH)
+ .append("=").append(filePath);
+
+ String encodedURL = RWT.getResponse().encodeURL(params.toString());
+ url.append(encodedURL);
+
+ return url.toString();
+ }
+
+ /* Dependency Injection */
+ // only used as a workaround to force the service instantiation
+ public void setOpenJcrFileService(OpenJcrFileService openJcrFileService) {
+ // do nothing.
+ }
+
+ public void setRepoService(RepoService repoService) {
+ this.repoService = repoService;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <!-- RCP Specific open JCR file command -->
+ <bean id="org.argeo.slc.client.rcp.openJcrFile" class="org.argeo.slc.client.ui.specific.OpenJcrFile"
+ scope="prototype">
+ <property name="repoService" ref="repoService" />
+ </bean>
+
+ <bean id="repoService" class="org.argeo.slc.repo.core.RepoServiceImpl">
+ <property name="repositoryFactory" ref="repositoryFactory" />
+ <property name="keyring" ref="keyring" />
+ <property name="nodeRepository" ref="nodeRepository" />
+ </bean>
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+ xmlns:osgi="http://www.springframework.org/schema/osgi"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi \r
+ http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+ http://www.springframework.org/schema/beans \r
+ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"\r
+ osgi:default-timeout="30000">\r
+\r
+ <beans:description>SLC UI RCP</beans:description>\r
+\r
+ <reference id="nodeRepository" interface="javax.jcr.Repository"\r
+ filter="(argeo.jcr.repository.alias=node)" />\r
+ <reference id="repositoryFactory" interface="javax.jcr.RepositoryFactory" />\r
+ <reference id="keyring" interface="org.argeo.security.crypto.CryptoKeyring" />\r
+\r
+</beans:beans>
\ No newline at end of file
</run>
</application>
</extension>
+
+ <!-- COMMANDS -->
+ <extension
+ point="org.eclipse.ui.commands">
+ <command
+ id="org.argeo.slc.client.rcp.openJcrFile"
+ defaultHandler="org.argeo.eclipse.spring.SpringCommandHandler"
+ name="Open Workspace Editor">
+ <commandParameter
+ id="param.repoNodePath"
+ name="Repo node path">
+ </commandParameter>
+ <commandParameter
+ id="param.repoUri"
+ name="Repo URI">
+ </commandParameter>
+ <commandParameter
+ id="param.workspaceName"
+ name="Workspace name">
+ </commandParameter>
+ <commandParameter
+ id="param.filePath"
+ name="File Path">
+ </commandParameter>
+ </command>
+ </extension>
<!-- RCP Specific, does not work with RAP -->
<extension
-<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">
+<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.argeo.slc</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
- <Bundle-Activator>org.argeo.slc.client.rcp.ClientRcpPlugin</Bundle-Activator>
+ <Bundle-Activator>org.argeo.slc.client.rcp.SlcRcpPlugin</Bundle-Activator>
<Require-Bundle>
org.eclipse.ui,
org.eclipse.core.runtime
</Require-Bundle>
<Import-Package>
+ org.argeo.eclipse.spring,
+ org.argeo.slc.repo.core,
+ javax.jcr.nodetype,
*,
</Import-Package>
</instructions>
<!-- SLC -->
<dependency>
<groupId>org.argeo.slc</groupId>
- <artifactId>org.argeo.slc.client.ui</artifactId>
+ <artifactId>org.argeo.slc.repo</artifactId>
<version>1.1.17-SNAPSHOT</version>
</dependency>
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.slc.client.rcp;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.resource.ImageRegistry;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.osgi.framework.BundleContext;
-
-/**
- * The activator class controls the plug-in life cycle
- */
-public class ClientRcpPlugin extends AbstractUIPlugin {
- public static final String PLUGIN_ID = "org.argeo.slc.client.rcp";
- private static ClientRcpPlugin plugin;
-
- public void start(BundleContext context) throws Exception {
- super.start(context);
- plugin = this;
- }
-
- public void stop(BundleContext context) throws Exception {
- plugin = null;
- super.stop(context);
- }
-
- public static ClientRcpPlugin getDefault() {
- return plugin;
- }
-
- @Override
- protected void initializeImageRegistry(ImageRegistry reg) {
- // TODO make it configurable
- reg.put("argeoTrayIcon",
- getImageDescriptor("icons/argeo-trayIcon-256.png"));
- }
-
- public static ImageDescriptor getImageDescriptor(String path) {
- return imageDescriptorFromPlugin(PLUGIN_ID, path);
- }
-}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.slc.client.rcp;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class SlcRcpPlugin extends AbstractUIPlugin {
+ public static final String PLUGIN_ID = "org.argeo.slc.client.rcp";
+ private static SlcRcpPlugin plugin;
+
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ public static SlcRcpPlugin getDefault() {
+ return plugin;
+ }
+
+ @Override
+ protected void initializeImageRegistry(ImageRegistry reg) {
+ // TODO make it configurable
+ reg.put("argeoTrayIcon",
+ getImageDescriptor("icons/argeo-trayIcon-256.png"));
+ }
+
+ public static ImageDescriptor getImageDescriptor(String path) {
+ return imageDescriptorFromPlugin(PLUGIN_ID, path);
+ }
+}
return;
// image
- Image trayImage = ClientRcpPlugin.getDefault().getImageRegistry()
+ Image trayImage = SlcRcpPlugin.getDefault().getImageRegistry()
.get("argeoTrayIcon");
trayItem.setImage(trayImage);
trayItem.setToolTipText("Argeo SLC");
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.slc.client.ui.specific;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+import org.apache.commons.io.IOUtils;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.client.rcp.SlcRcpPlugin;
+import org.argeo.slc.repo.RepoService;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+
+/**
+ * RCP specific command handler to open a file retrieved from a local or distant
+ * JCR Repository.
+ */
+public class OpenJcrFile extends AbstractHandler {
+ // private final static Log log = LogFactory.getLog(OpenJcrFile.class);
+
+ // Here is the trick that enable single sourcing: the ID is determined at
+ // runtime. ALWAYS use this public variable to call the command.
+ public final static String ID = SlcRcpPlugin.PLUGIN_ID + ".openJcrFile";
+
+ public final static String PARAM_REPO_NODE_PATH = "param.repoNodePath";
+ public final static String PARAM_REPO_URI = "param.repoUri";
+ public final static String PARAM_WORKSPACE_NAME = "param.workspaceName";
+ public final static String PARAM_FILE_PATH = "param.filePath";
+
+ /* DEPENDENCY INJECTION */
+ private RepoService repoService;
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ String repoNodePath = event.getParameter(PARAM_REPO_NODE_PATH);
+ String repoUri = event.getParameter(PARAM_REPO_URI);
+ String wkspName = event.getParameter(PARAM_WORKSPACE_NAME);
+ String filePath = event.getParameter(PARAM_FILE_PATH);
+
+ // TODO sanity check
+ if (filePath == null || "".equals(filePath.trim()))
+ return null;
+ retrieveAndOpen(repoNodePath, repoUri, wkspName, filePath);
+
+ return null;
+ }
+
+ protected void retrieveAndOpen(String repoNodePath, String repoUri,
+ String wkspName, String filePath) {
+ Session businessSession = null;
+ try {
+ businessSession = repoService.getRemoteSession(repoNodePath,
+ repoUri, wkspName);
+ Node result = businessSession.getNode(filePath);
+
+ boolean isValid = true;
+ Node child = null;
+ if (!result.isNodeType(NodeType.NT_FILE))
+ isValid = false;
+ else {
+ child = result.getNode(Property.JCR_CONTENT);
+ if (!(child.isNodeType(NodeType.NT_RESOURCE) || child
+ .hasProperty(Property.JCR_DATA)))
+ isValid = false;
+ }
+
+ if (!isValid)
+ return;
+
+ InputStream fis = null;
+ String prefix = "", extension = "";
+ String fileName = JcrUtils.lastPathElement(filePath);
+ int ind = fileName.lastIndexOf('.');
+ if (ind > 0) {
+ prefix = fileName.substring(0, ind);
+ extension = fileName.substring(ind);
+ }
+ try {
+
+ fis = (InputStream) child.getProperty(Property.JCR_DATA)
+ .getBinary().getStream();
+ File file = createTmpFile(prefix, extension, fis);
+ Desktop desktop = null;
+ if (Desktop.isDesktopSupported()) {
+ desktop = Desktop.getDesktop();
+ }
+ desktop.open(file);
+ } catch (Exception e) {
+ throw new SlcException(
+ "Stream error while opening file " + filePath
+ + " from repo " + repoUri == null ? repoNodePath
+ : repoUri, e);
+ } finally {
+ IOUtils.closeQuietly(fis);
+ }
+ } catch (RepositoryException e) {
+ throw new SlcException("Unexpected error while "
+ + "getting repoNode info for repoNode at path "
+ + repoNodePath, e);
+ } finally {
+ JcrUtils.logoutQuietly(businessSession);
+ }
+ }
+
+ private File createTmpFile(String prefix, String suffix, InputStream is) {
+ File tmpFile = null;
+ OutputStream os = null;
+ try {
+ tmpFile = File.createTempFile(prefix, suffix);
+ os = new FileOutputStream(tmpFile);
+ IOUtils.copy(is, os);
+ } catch (IOException e) {
+ throw new SlcException("Cannot open file " + prefix + "." + suffix,
+ e);
+ } finally {
+ IOUtils.closeQuietly(os);
+ }
+ return tmpFile;
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setRepoService(RepoService repoService) {
+ this.repoService = repoService;
+ }
+}
\ No newline at end of file
<property name="workspace" value="org.argeo.tp-1.3.1" />
</bean>
- <bean id="repoService" class="org.argeo.slc.client.ui.dist.RepoServiceImpl">
+ <bean id="repoService" class="org.argeo.slc.repo.core.RepoServiceImpl">
<property name="repositoryFactory" ref="repositoryFactory" />
<property name="keyring" ref="keyring" />
<property name="nodeRepository" ref="nodeRepository" />
javax.jcr.nodetype,
javax.jcr.security,
aQute.lib.*;resolution:=optional,
+ org.argeo.slc.client.ui.specific,
*
</Import-Package>
</instructions>
</plugins>
</build>
<dependencies>
+
+ <!-- Single sourcing - we build against RCP -->
<dependency>
- <groupId>org.argeo.commons.base</groupId>
- <artifactId>org.argeo.util</artifactId>
- <version>${version.argeo-commons}</version>
+ <groupId>org.argeo.slc</groupId>
+ <artifactId>org.argeo.slc.client.rcp</artifactId>
+ <version>1.1.17-SNAPSHOT</version>
+ <scope>provided</scope>
</dependency>
-
+
<!-- Commons UI -->
<dependency>
<groupId>org.argeo.commons.base</groupId>
<scope>provided</scope>
</dependency>
-
<!-- SLC repo -->
<dependency>
<groupId>org.argeo.slc</groupId>
<groupId>org.argeo.tp</groupId>
<artifactId>biz.aQute.bndlib</artifactId>
</dependency>
+
+ <!-- Argeo Base dependencies -->
+ <dependency>
+ <groupId>org.argeo.commons.base</groupId>
+ <artifactId>org.argeo.util</artifactId>
+ <version>${version.argeo-commons}</version>
+ </dependency>
+
</dependencies>
</project>
\ No newline at end of file
+++ /dev/null
-package org.argeo.slc.client.ui.dist;
-
-import javax.jcr.Session;
-
-/** Start factorisation of the session management using a manager service */
-public interface RepoService {
-
- /**
- * Returns a corresponding session given the current context. Caller must
- * close the session once it as been used
- */
- public Session getRemoteSession(String repoNodePath, String uri,
- String workspaceName);
-}
+++ /dev/null
-package org.argeo.slc.client.ui.dist;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryFactory;
-import javax.jcr.Session;
-
-import org.argeo.slc.repo.RepoUtils;
-import org.argeo.util.security.Keyring;
-
-public class RepoServiceImpl implements RepoService {
-
- /* DEPENDENCY INJECTION */
- private Repository nodeRepository;
- private RepositoryFactory repositoryFactory;
- private Keyring keyring;
-
- public Session getRemoteSession(String repoNodePath, String uri,
- String workspaceName) {
- return RepoUtils.getRemoteSession(repositoryFactory, keyring,
- nodeRepository, repoNodePath, uri, workspaceName);
- }
-
- /* DEPENDENCY INJECTION */
- public void setNodeRepository(Repository nodeRepository) {
- this.nodeRepository = nodeRepository;
- }
-
- public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
- this.repositoryFactory = repositoryFactory;
- }
-
- public void setKeyring(Keyring keyring) {
- this.keyring = keyring;
- }
-
-}
import org.argeo.jcr.JcrUtils;
import org.argeo.slc.client.ui.dist.DistPlugin;
-import org.argeo.slc.client.ui.dist.RepoService;
import org.argeo.slc.client.ui.dist.model.RepoElem;
+import org.argeo.slc.repo.RepoService;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
package org.argeo.slc.client.ui.dist.commands;
import org.argeo.slc.client.ui.dist.DistPlugin;
-import org.argeo.slc.client.ui.dist.RepoService;
import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
import org.argeo.slc.client.ui.dist.wizards.GenerateBinariesWizard;
+import org.argeo.slc.repo.RepoService;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.argeo.jcr.JcrUtils;
import org.argeo.slc.SlcException;
import org.argeo.slc.client.ui.dist.DistPlugin;
-import org.argeo.slc.client.ui.dist.RepoService;
import org.argeo.slc.client.ui.dist.editors.ArtifactVersionEditor;
import org.argeo.slc.client.ui.dist.editors.ModularDistVersionEditor;
import org.argeo.slc.client.ui.dist.editors.ModuleEditorInput;
import org.argeo.slc.jcr.SlcTypes;
+import org.argeo.slc.repo.RepoService;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.argeo.jcr.JcrUtils;
import org.argeo.slc.SlcException;
import org.argeo.slc.client.ui.dist.DistPlugin;
-import org.argeo.slc.client.ui.dist.RepoService;
import org.argeo.slc.jcr.SlcNames;
+import org.argeo.slc.repo.RepoService;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
package org.argeo.slc.client.ui.dist.editors;
import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.utils.CommandUtils;
import org.argeo.slc.SlcException;
import org.argeo.slc.client.ui.dist.DistConstants;
import org.argeo.slc.client.ui.dist.utils.AbstractHyperlinkListener;
+import org.argeo.slc.client.ui.specific.OpenJcrFile;
import org.argeo.slc.jcr.SlcNames;
import org.argeo.slc.repo.RepoConstants;
import org.argeo.slc.repo.RepoUtils;
.getString() : "N/A");
createHyperlink(parent, "Licence", DistConstants.SLC_BUNDLE_LICENCE);
- addSourceSourcesLink(parent);
+ addSourceLink(parent);
} catch (RepositoryException re) {
throw new SlcException("Unable to get bundle name for node "
+ bundle, re);
}
// helper to check if sources are available
- private void addSourceSourcesLink(Composite parent) {
+ private void addSourceLink(Composite parent) {
try {
String srcPath = RepoUtils.relatedPdeSourcePath(
RepoConstants.DEFAULT_ARTIFACTS_BASE_PATH, bundle);
if (!bundle.getSession().nodeExists(srcPath)) {
createLT(parent, "Sources", "N/A");
} else {
- Node sourcesNode = bundle.getSession().getNode(srcPath);
+ final Node sourcesNode = bundle.getSession().getNode(srcPath);
String srcName = null;
if (sourcesNode.hasProperty(SlcNames.SLC_SYMBOLIC_NAME))
@Override
public void linkActivated(HyperlinkEvent e) {
try {
- System.out.println("CLICK on Sources link");
+ ModuleEditorInput editorInput = (ModuleEditorInput) getEditorInput();
+ Map<String, String> params = new HashMap<String, String>();
+ params.put(OpenJcrFile.PARAM_REPO_NODE_PATH,
+ editorInput.getRepoNodePath());
+ params.put(OpenJcrFile.PARAM_REPO_URI,
+ editorInput.getUri());
+ params.put(OpenJcrFile.PARAM_WORKSPACE_NAME,
+ editorInput.getWorkspaceName());
+ params.put(OpenJcrFile.PARAM_FILE_PATH,
+ sourcesNode.getPath());
+ CommandUtils.callCommand(OpenJcrFile.ID, params);
} catch (Exception ex) {
throw new SlcException("error opening browser", ex); //$NON-NLS-1$
}
import org.argeo.slc.SlcException;
import org.argeo.slc.client.ui.dist.DistPlugin;
import org.argeo.slc.client.ui.dist.PrivilegedJob;
-import org.argeo.slc.client.ui.dist.RepoService;
import org.argeo.slc.client.ui.dist.utils.ViewerUtils;
import org.argeo.slc.jcr.SlcTypes;
import org.argeo.slc.repo.RepoConstants;
+import org.argeo.slc.repo.RepoService;
import org.argeo.slc.repo.RepoUtils;
import org.argeo.slc.repo.maven.GenerateBinaries;
import org.eclipse.core.runtime.IProgressMonitor;
</plugins>
</build>
<dependencies>
+ <!-- Single sourcing - we build against RCP -->
+ <dependency>
+ <groupId>org.argeo.slc</groupId>
+ <artifactId>org.argeo.slc.client.rcp</artifactId>
+ <version>1.1.17-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+
<!-- SLC -->
<dependency>
<groupId>org.argeo.slc</groupId>
<name>SLC Eclipse Plugins</name>
<packaging>pom</packaging>
<modules>
- <module>org.argeo.slc.client.ui</module>
- <module>org.argeo.slc.client.ui.dist</module>
<module>org.argeo.slc.client.rcp</module>
<module>org.argeo.slc.client.rap</module>
+ <module>org.argeo.slc.client.ui</module>
+ <module>org.argeo.slc.client.ui.dist</module>
</modules>
<build>
<plugins>
-<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">
+<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.argeo.commons</groupId>
<artifactId>argeo-slc</artifactId>
<packaging>pom</packaging>
<name>Argeo SLC</name>
+ <description>SLC is a framework integrating various build, deployment and testing technologies in order to build specific application life cycle management systems.</description>
<version>1.1.17-SNAPSHOT</version>
<properties>
<developmentCycle.slc>1.1</developmentCycle.slc>
package org.argeo.slc.repo;
import javax.jcr.Node;
+import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;
import org.apache.commons.logging.Log;
import org.argeo.slc.aether.AetherUtils;
import org.argeo.slc.jcr.SlcNames;
import org.argeo.slc.jcr.SlcTypes;
+import org.osgi.framework.Constants;
import org.sonatype.aether.artifact.Artifact;
/**
* name doesn't start with the artifact id (in order to skip Maven metadata XML
* files and other non artifact files).
*/
-public class ArtifactIndexer implements NodeIndexer {
+public class ArtifactIndexer implements NodeIndexer, SlcNames {
private Log log = LogFactory.getLog(ArtifactIndexer.class);
private Boolean force = false;
md5.getBytes());
}
+ // Create a default pom only with artifact coordinates if none
+ // already exist
+ String fileNodeName = fileNode.getName();
+ String pomName= null;
+ if (fileNodeName.endsWith(".jar"))
+ pomName = fileNodeName.substring(0, fileNodeName.length()-".jar".length()) + ".pom";
+
+ if (pomName != null && !fileNode.getParent().hasNode(pomName)) {
+ String pom = generatePomForBundle(fileNode);
+ Node pomNode = JcrUtils.copyBytesAsFile(fileNode.getParent(),
+ pomName, pom.getBytes());
+ // corresponding check sums
+ String sha = JcrUtils.checksumFile(pomNode, "SHA-1");
+ JcrUtils.copyBytesAsFile(fileNode.getParent(), pomName + ".sha1",
+ sha.getBytes());
+ String md5 = JcrUtils.checksumFile(fileNode, "MD5");
+ JcrUtils.copyBytesAsFile(fileNode.getParent(), pomName +".md5",
+ md5.getBytes());
+ }
+
// set higher levels
Node artifactVersionBase = fileNode.getParent();
if (!artifactVersionBase
this.force = force;
}
-}
+ private String generatePomForBundle(Node n) throws RepositoryException {
+ StringBuffer p = new StringBuffer();
+
+ // XML header
+ p.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ p.append("<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\">\n");
+ p.append("<modelVersion>4.0.0</modelVersion>");
+
+ // Artifact
+ p.append("<groupId>").append(JcrUtils.get(n, SLC_GROUP_ID))
+ .append("</groupId>\n");
+ p.append("<artifactId>").append(JcrUtils.get(n, SLC_ARTIFACT_ID))
+ .append("</artifactId>\n");
+ p.append("<version>").append(JcrUtils.get(n, SLC_ARTIFACT_VERSION))
+ .append("</version>\n");
+ p.append("<packaging>pom</packaging>\n");
+ if (n.hasProperty(SLC_ + Constants.BUNDLE_NAME))
+ p.append("<name>")
+ .append(JcrUtils.get(n, SLC_ + Constants.BUNDLE_NAME))
+ .append("</name>\n");
+ if (n.hasProperty(SLC_ + Constants.BUNDLE_DESCRIPTION))
+ p.append("<description>")
+ .append(JcrUtils
+ .get(n, SLC_ + Constants.BUNDLE_DESCRIPTION))
+ .append("</description>\n");
+ p.append("</project>\n");
+ return p.toString();
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.argeo.slc.repo;
+
+import javax.jcr.Session;
+
+/** Start factorisation of the session management using a manager service */
+public interface RepoService {
+
+ /**
+ * Returns a corresponding session given the current context. Caller must
+ * close the session once it has been used
+ */
+ public Session getRemoteSession(String repoNodePath, String uri,
+ String workspaceName);
+}
--- /dev/null
+package org.argeo.slc.repo.core;
+
+import javax.jcr.LoginException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
+import javax.jcr.Session;
+
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.repo.RepoService;
+import org.argeo.slc.repo.RepoUtils;
+import org.argeo.util.security.Keyring;
+
+/**
+ * Work in Progress - enhance this. First implementation of a service that
+ * centralizes session management in an argeo SLC context, repositories are
+ * either defined using an URI and a workspace name in a anonymous context or
+ * using connection information that are store in a corresponding node in the
+ * local repository home
+ */
+public class RepoServiceImpl implements RepoService {
+
+ /* DEPENDENCY INJECTION */
+ private Repository nodeRepository;
+ private RepositoryFactory repositoryFactory;
+ private Keyring keyring;
+
+ public Session getRemoteSession(String repoNodePath, String uri,
+ String workspaceName) {
+
+ // TODO remove this. Only usefull while investigating the RAP login
+ // problem
+ Session session = null;
+ try {
+ session = nodeRepository.login();
+ } catch (LoginException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (RepositoryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+
+ return RepoUtils.getRemoteSession(repositoryFactory, keyring,
+ nodeRepository, repoNodePath, uri, workspaceName);
+ }
+
+ /* DEPENDENCY INJECTION */
+ public void setNodeRepository(Repository nodeRepository) {
+ this.nodeRepository = nodeRepository;
+ }
+
+ public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
+ this.repositoryFactory = repositoryFactory;
+ }
+
+ public void setKeyring(Keyring keyring) {
+ this.keyring = keyring;
+ }
+}
\ No newline at end of file