mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-16 17:55:15 +00:00
First-cut RepoAdmin Service for managing models & messages in the repo (not yet enabled)
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6682 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
parent
964f88773b
commit
9f539ce6e7
@ -30,6 +30,9 @@
|
|||||||
<import resource="classpath:alfresco/policy-context.xml" />
|
<import resource="classpath:alfresco/policy-context.xml" />
|
||||||
<import resource="classpath:alfresco/import-export-context.xml" />
|
<import resource="classpath:alfresco/import-export-context.xml" />
|
||||||
<import resource="classpath:alfresco/bootstrap-context.xml" />
|
<import resource="classpath:alfresco/bootstrap-context.xml" />
|
||||||
|
|
||||||
|
<import resource="classpath:alfresco/repo-admin-context.xml"/>
|
||||||
|
|
||||||
<import resource="classpath:alfresco/workflow-context.xml" />
|
<import resource="classpath:alfresco/workflow-context.xml" />
|
||||||
<import resource="classpath:alfresco/jcr-api-context.xml" />
|
<import resource="classpath:alfresco/jcr-api-context.xml" />
|
||||||
<import resource="classpath:alfresco/avm-services-context.xml" />
|
<import resource="classpath:alfresco/avm-services-context.xml" />
|
||||||
|
1
config/alfresco/messages/repoadmin-interpreter-help.properties
Executable file
1
config/alfresco/messages/repoadmin-interpreter-help.properties
Executable file
@ -0,0 +1 @@
|
|||||||
|
repoadmin_console.help=alfresco/messages/repoadmin-interpreter-help.txt
|
97
config/alfresco/messages/repoadmin-interpreter-help.txt
Executable file
97
config/alfresco/messages/repoadmin-interpreter-help.txt
Executable file
@ -0,0 +1,97 @@
|
|||||||
|
##
|
||||||
|
## Meta commands
|
||||||
|
##
|
||||||
|
|
||||||
|
ok> help
|
||||||
|
|
||||||
|
List this help.
|
||||||
|
|
||||||
|
ok> r
|
||||||
|
|
||||||
|
Repeat last command.
|
||||||
|
|
||||||
|
|
||||||
|
ok> quit | exit
|
||||||
|
|
||||||
|
Quit this console.
|
||||||
|
|
||||||
|
##
|
||||||
|
## General Repo Admin Commands
|
||||||
|
##
|
||||||
|
|
||||||
|
ok> show file <fileClassPath>
|
||||||
|
|
||||||
|
Output the contents of the file located at <fileClassPath>.
|
||||||
|
|
||||||
|
<fileClassPath> class path to a file
|
||||||
|
|
||||||
|
e.g. show file alfresco/extension/xxxModel.xml
|
||||||
|
e.g. show file alfresco/extension/yyy-messages.properties
|
||||||
|
|
||||||
|
ok> show file-list <filesClassPath>
|
||||||
|
|
||||||
|
Show list of files located at <filesClassPath> with first match being listed for each filename.
|
||||||
|
|
||||||
|
<filesClassPath> class path to a list of files. Wildcard * is allowed. For example, to see
|
||||||
|
a list of message resource bundles that would be loaded, use: /path1/path2/bundlename*.properties
|
||||||
|
|
||||||
|
e.g. show file-list alfresco/extension/*
|
||||||
|
e.g. show file-list alfresco/extension/*Model.xml
|
||||||
|
e.g. show file-list alfresco/extension/zzz-messages*.properties
|
||||||
|
|
||||||
|
##
|
||||||
|
## Model Admin Commands
|
||||||
|
##
|
||||||
|
|
||||||
|
ok> show models
|
||||||
|
|
||||||
|
Show deployed models - that are stored in the repository data dictionary.
|
||||||
|
|
||||||
|
ok> deploy model <fileClassPath>
|
||||||
|
|
||||||
|
Upload model to repository and into runtime data dictionary. This will also
|
||||||
|
set the model as active.
|
||||||
|
|
||||||
|
e.g. deploy model alfresco/extension/exampleModel.xml
|
||||||
|
|
||||||
|
ok> undeploy model <modelFileName>
|
||||||
|
|
||||||
|
Permanently delete model from repository (all versions) and from runtime data dictionary.
|
||||||
|
|
||||||
|
e.g. undeploy model exampleModel.xml
|
||||||
|
|
||||||
|
ok> reload model <modelFileName>
|
||||||
|
|
||||||
|
Reload (or load for first time) from repository into runtime data dictionary.
|
||||||
|
|
||||||
|
e.g. reload model exampleModel.xml
|
||||||
|
|
||||||
|
##
|
||||||
|
## Message Admin Commands
|
||||||
|
##
|
||||||
|
|
||||||
|
ok> show messages
|
||||||
|
|
||||||
|
Show deployed message resource bundles - that are stored in the repository data dictionary.
|
||||||
|
|
||||||
|
ok> deploy messages <resourceBundleClassPath>
|
||||||
|
|
||||||
|
Upload message resource bundle to repository and runtime message service.
|
||||||
|
|
||||||
|
e.g. deploy messages alfresco/extension/lifecycle-messages
|
||||||
|
|
||||||
|
ok> undeploy messages <resourceBundleBaseName>
|
||||||
|
|
||||||
|
Remove message resource bundle from repository and from runtime message service.
|
||||||
|
|
||||||
|
e.g. undeploy messages lifecycle-messages
|
||||||
|
|
||||||
|
ok> reload messages <resourceBundleBaseName>
|
||||||
|
|
||||||
|
Reload message resource bundle from repository into runtime message service.
|
||||||
|
|
||||||
|
e.g. undeploy messages lifecycle-messages
|
||||||
|
|
||||||
|
##
|
||||||
|
## end
|
||||||
|
##
|
@ -1419,4 +1419,36 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Repository Admin Service -->
|
||||||
|
|
||||||
|
<bean id="RepoAdminService" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||||
|
<property name="proxyInterfaces">
|
||||||
|
<value>org.alfresco.service.cmr.admin.RepoAdminService</value>
|
||||||
|
</property>
|
||||||
|
<property name="target">
|
||||||
|
<ref bean="repoAdminService"/>
|
||||||
|
</property>
|
||||||
|
<property name="interceptorNames">
|
||||||
|
<list>
|
||||||
|
<idref local="RepoAdminService_transaction"/>
|
||||||
|
<idref local="AuditMethodInterceptor"/>
|
||||||
|
<idref local="exceptionTranslator"/>
|
||||||
|
<idref bean="RepoAdminService_security"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="RepoAdminService_transaction" class="org.springframework.transaction.interceptor.TransactionInterceptor">
|
||||||
|
<property name="transactionManager">
|
||||||
|
<ref bean="transactionManager"/>
|
||||||
|
</property>
|
||||||
|
<property name="transactionAttributes">
|
||||||
|
<props>
|
||||||
|
<prop key="get*">${server.transaction.mode.readOnly}</prop>
|
||||||
|
<prop key="*">${server.transaction.mode.default}</prop>
|
||||||
|
</props>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
@ -795,4 +795,12 @@
|
|||||||
|
|
||||||
<bean id="AuditService_security" class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
|
<bean id="AuditService_security" class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
|
||||||
|
|
||||||
|
<!-- ======================== -->
|
||||||
|
<!-- Repository Admin Service -->
|
||||||
|
<!-- ======================== -->
|
||||||
|
|
||||||
|
<!-- TODO: Add repository admin security -->
|
||||||
|
|
||||||
|
<bean id="RepoAdminService_security" class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
|
||||||
|
|
||||||
</beans>
|
</beans>
|
92
config/alfresco/repo-admin-context.xml
Executable file
92
config/alfresco/repo-admin-context.xml
Executable file
@ -0,0 +1,92 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||||
|
|
||||||
|
<beans>
|
||||||
|
|
||||||
|
<bean id="repoAdminService" class="org.alfresco.repo.admin.RepoAdminServiceImpl">
|
||||||
|
|
||||||
|
<property name="dictionaryDAO" ref="dictionaryDAO"/>
|
||||||
|
<property name="searchService" ref="SearchService"/>
|
||||||
|
<property name="nodeService" ref="NodeService"/>
|
||||||
|
<property name="contentService" ref="ContentService"/>
|
||||||
|
<property name="namespaceService" ref="namespaceService"/>
|
||||||
|
<property name="messageService" ref="messageService"/>
|
||||||
|
|
||||||
|
<property name="repositoryModelsLocation" ref="customModelsRepositoryLocation"/>
|
||||||
|
<property name="repositoryMessagesLocation" ref="customMessagesRepositoryLocation"/>
|
||||||
|
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="repoAdminInterpreter" class="org.alfresco.repo.admin.RepoAdminInterpreter">
|
||||||
|
|
||||||
|
<property name="transactionService" ref="transactionComponent"/>
|
||||||
|
<property name="repoAdminService" ref="RepoAdminService"/>
|
||||||
|
<property name="tenantService" ref="tenantService"/>
|
||||||
|
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="repoAdminInterpreterHelp" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
|
||||||
|
|
||||||
|
<property name="resourceBundles">
|
||||||
|
<list>
|
||||||
|
<value>alfresco.messages.repoadmin-interpreter-help</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Load any additional models/messages from repo into data dictionary -->
|
||||||
|
<!-- note: needs to match import-export-context.xml locations -->
|
||||||
|
|
||||||
|
<bean id="customModelsRepositoryLocation" class="org.alfresco.repo.dictionary.RepositoryLocation">
|
||||||
|
<!-- other properties will be defaulted, but can be overriden here -->
|
||||||
|
<property name="path">
|
||||||
|
<value>/app:company_home/app:dictionary/app:models</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="customMessagesRepositoryLocation" class="org.alfresco.repo.dictionary.RepositoryLocation">
|
||||||
|
<!-- other properties will be defaulted, but can be overriden here -->
|
||||||
|
<property name="path">
|
||||||
|
<value>/app:company_home/app:dictionary/app:messages</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="dictionaryRepositoryBootstrap" class="org.alfresco.repo.dictionary.DictionaryRepositoryBootstrap">
|
||||||
|
|
||||||
|
<property name="dictionaryDAO">
|
||||||
|
<ref bean="dictionaryDAO"/>
|
||||||
|
</property>
|
||||||
|
<property name="contentService">
|
||||||
|
<ref bean="contentService"/>
|
||||||
|
</property>
|
||||||
|
<property name="searchService">
|
||||||
|
<ref bean="searchService"/>
|
||||||
|
</property>
|
||||||
|
<property name="transactionService">
|
||||||
|
<ref bean="transactionComponent"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="namespaceService"><ref bean="namespaceService"/></property>
|
||||||
|
<property name="nodeService"><ref bean="NodeService"/></property>
|
||||||
|
<property name="messageService"><ref bean="messageService"/></property>
|
||||||
|
|
||||||
|
<property name="tenantService"><ref bean="tenantService"/></property>
|
||||||
|
<property name="tenantDeployerService" ref="tenantAdminService"/>
|
||||||
|
|
||||||
|
<property name="repositoryModelsLocations">
|
||||||
|
<list>
|
||||||
|
<ref bean="customModelsRepositoryLocation" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="repositoryMessagesLocations">
|
||||||
|
<list>
|
||||||
|
<ref bean="customMessagesRepositoryLocation" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
347
source/java/org/alfresco/repo/admin/RepoAdminInterpreter.java
Executable file
347
source/java/org/alfresco/repo/admin/RepoAdminInterpreter.java
Executable file
@ -0,0 +1,347 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.admin;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.i18n.I18NUtil;
|
||||||
|
import org.alfresco.service.cmr.admin.RepoAdminService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interactive console for (first cut) Repository Admin Service / API.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RepoAdminInterpreter extends BaseInterpreter
|
||||||
|
{
|
||||||
|
// dependencies
|
||||||
|
private RepoAdminService repoAdminService;
|
||||||
|
|
||||||
|
|
||||||
|
public void setRepoAdminService(RepoAdminService repoAdminService)
|
||||||
|
{
|
||||||
|
this.repoAdminService = repoAdminService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static BaseInterpreter getConsoleBean(ApplicationContext context)
|
||||||
|
{
|
||||||
|
return (RepoAdminInterpreter)context.getBean("repoAdminInterpreter");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean hasAuthority(String username)
|
||||||
|
{
|
||||||
|
// must be an "admin" for repository administration
|
||||||
|
return ((username != null) && (tenantService.getBaseNameUser(username).equals(BaseInterpreter.DEFAULT_ADMIN)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a single command using the BufferedReader passed in for any data needed.
|
||||||
|
*
|
||||||
|
* TODO: Use decent parser!
|
||||||
|
*
|
||||||
|
* @param line The unparsed command
|
||||||
|
* @return The textual output of the command.
|
||||||
|
*/
|
||||||
|
protected String executeCommand(String line)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
String[] command = line.split(" ");
|
||||||
|
if (command.length == 0)
|
||||||
|
{
|
||||||
|
command = new String[1];
|
||||||
|
command[0] = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||||
|
PrintStream out = new PrintStream(bout);
|
||||||
|
|
||||||
|
// repeat last command?
|
||||||
|
if (command[0].equals("r"))
|
||||||
|
{
|
||||||
|
if (lastCommand == null)
|
||||||
|
{
|
||||||
|
return "No command entered yet.";
|
||||||
|
}
|
||||||
|
return "repeating command " + lastCommand + "\n\n" + executeCommand(lastCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember last command
|
||||||
|
lastCommand = line;
|
||||||
|
|
||||||
|
// execute command
|
||||||
|
if (command[0].equals("help"))
|
||||||
|
{
|
||||||
|
String helpFile = I18NUtil.getMessage("repoadmin_console.help");
|
||||||
|
ClassPathResource helpResource = new ClassPathResource(helpFile);
|
||||||
|
byte[] helpBytes = new byte[500];
|
||||||
|
InputStream helpStream = helpResource.getInputStream();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int read = helpStream.read(helpBytes);
|
||||||
|
while (read != -1)
|
||||||
|
{
|
||||||
|
bout.write(helpBytes, 0, read);
|
||||||
|
read = helpStream.read(helpBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
helpStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[0].equals("show"))
|
||||||
|
{
|
||||||
|
if (command.length < 2)
|
||||||
|
{
|
||||||
|
return "Syntax Error.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[1].equals("file"))
|
||||||
|
{
|
||||||
|
if (command.length != 3)
|
||||||
|
{
|
||||||
|
return "Syntax Error.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassPathResource file = new ClassPathResource(command[2]);
|
||||||
|
InputStream fileStream = file.getInputStream();
|
||||||
|
|
||||||
|
if (fileStream != null)
|
||||||
|
{
|
||||||
|
byte[] fileBytes = new byte[500];
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int read = fileStream.read(fileBytes);
|
||||||
|
while (read != -1)
|
||||||
|
{
|
||||||
|
bout.write(fileBytes, 0, read);
|
||||||
|
read = fileStream.read(fileBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
fileStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.println("No matching file found: " + command[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[1].equals("file-list"))
|
||||||
|
{
|
||||||
|
if (command.length != 3)
|
||||||
|
{
|
||||||
|
return "Syntax Error.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// note: classpath should be in form path1/path2/path3/name*
|
||||||
|
// wildcard * is allowed, e.g. abc/def/workflow-messages*.properties
|
||||||
|
String pattern = "classpath*:" + command[2];
|
||||||
|
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||||
|
|
||||||
|
Resource[] resources = resolver.getResources(pattern);
|
||||||
|
ArrayList<String> names = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (resources != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < resources.length; i++)
|
||||||
|
{
|
||||||
|
String filename = resources[i].getFilename();
|
||||||
|
if (! names.contains(filename))
|
||||||
|
{
|
||||||
|
out.println("resource: " + filename + ", url: " + resources[i].getURL());
|
||||||
|
names.add(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.println("No matching files found: " + command[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[1].equals("models"))
|
||||||
|
{
|
||||||
|
List<RepoModelDefinition> models = repoAdminService.getModels();
|
||||||
|
|
||||||
|
if ((models != null) && (models.size() > 0))
|
||||||
|
{
|
||||||
|
for (RepoModelDefinition model : models)
|
||||||
|
{
|
||||||
|
out.println(model.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.println("No additional models have been deployed to the Alfresco Repository");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[1].equals("messages"))
|
||||||
|
{
|
||||||
|
List<String> messageResources = repoAdminService.getMessageBundles();
|
||||||
|
|
||||||
|
if ((messageResources != null) && (messageResources.size() > 0))
|
||||||
|
{
|
||||||
|
for (String messageResourceName : messageResources)
|
||||||
|
{
|
||||||
|
out.println("message resource bundle: " + messageResourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.println("No additional messages resource bundles have been deployed to the Alfresco Repository");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "No such sub-command, try 'help'.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[0].equals("deploy"))
|
||||||
|
{
|
||||||
|
if (command.length != 3)
|
||||||
|
{
|
||||||
|
return "Syntax Error.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command[1].equals("model"))
|
||||||
|
{
|
||||||
|
ClassPathResource file = new ClassPathResource(command[2]);
|
||||||
|
|
||||||
|
InputStream fileStream = file.getInputStream();
|
||||||
|
|
||||||
|
String modelFileName = file.getFilename();
|
||||||
|
QName modelQName = repoAdminService.deployModel(fileStream, modelFileName);
|
||||||
|
out.println("Model deployed: " + modelFileName + " [" + modelQName + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[1].equals("messages"))
|
||||||
|
{
|
||||||
|
String bundleBasePath = command[2];
|
||||||
|
String bundleBaseName = repoAdminService.deployMessageBundle(bundleBasePath);
|
||||||
|
out.println("Message resource bundle deployed: " + bundleBaseName);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "No such sub-command, try 'help'.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[0].equals("reload"))
|
||||||
|
{
|
||||||
|
if (command.length != 2)
|
||||||
|
{
|
||||||
|
return "Syntax Error.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[1].equals("model"))
|
||||||
|
{
|
||||||
|
String modelFileName = command[2];
|
||||||
|
QName modelQName = repoAdminService.reloadModel(modelFileName);
|
||||||
|
out.println("Model (re-)loaded: " + modelFileName + " [" + modelQName + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[1].equals("messages"))
|
||||||
|
{
|
||||||
|
String bundleBaseName = command[2];
|
||||||
|
repoAdminService.reloadMessageBundle(bundleBaseName);
|
||||||
|
out.println("Message resource bundle (re-)loaded: " + bundleBaseName);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "No such sub-command, try 'help'.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[0].equals("undeploy"))
|
||||||
|
{
|
||||||
|
if (command.length != 3)
|
||||||
|
{
|
||||||
|
return "Syntax Error.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command[1].equals("model"))
|
||||||
|
{
|
||||||
|
String modelFileName = command[2];
|
||||||
|
QName modelQName = repoAdminService.undeployModel(modelFileName);
|
||||||
|
out.println("Model undeployed: " + modelFileName + " [" + modelQName + "]");
|
||||||
|
|
||||||
|
out.println("");
|
||||||
|
out.println("Remaining models:");
|
||||||
|
out.print(executeCommand("show models"));
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (command[1].equals("messages"))
|
||||||
|
{
|
||||||
|
String bundleBaseName = command[2];
|
||||||
|
repoAdminService.undeployMessageBundle(bundleBaseName);
|
||||||
|
out.println("Message resource bundle undeployed: " + bundleBaseName);
|
||||||
|
|
||||||
|
out.println("");
|
||||||
|
out.println("Remaining message resource bundles:");
|
||||||
|
out.print(executeCommand("show messages"));
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "No such sub-command, try 'help'.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "No such command, try 'help'.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
out.flush();
|
||||||
|
String retVal = new String(bout.toByteArray());
|
||||||
|
out.close();
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
}
|
66
source/java/org/alfresco/repo/admin/RepoAdminService.java
Executable file
66
source/java/org/alfresco/repo/admin/RepoAdminService.java
Executable file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.admin;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repository Admin Service interface.
|
||||||
|
* <p>
|
||||||
|
* This interface provides certain repository administrative methods to:
|
||||||
|
*
|
||||||
|
* - deploy/undeploy custom content models to/from repository
|
||||||
|
* - deploy/undeploy custom messages resources to/from repository
|
||||||
|
*
|
||||||
|
* Initially, this will support models and messages used by workflow process definitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface RepoAdminService
|
||||||
|
{
|
||||||
|
/* Custom models managed in the repository */
|
||||||
|
|
||||||
|
public List<RepoModelDefinition> getModels();
|
||||||
|
|
||||||
|
public QName deployModel(InputStream modelStream, String modelFileName);
|
||||||
|
|
||||||
|
public QName undeployModel(String modelFileName);
|
||||||
|
|
||||||
|
public QName reloadModel(String modelFileName);
|
||||||
|
|
||||||
|
/* Custom message/resource bundles managed in the repository */
|
||||||
|
|
||||||
|
public List<String> getMessageBundles();
|
||||||
|
|
||||||
|
public String deployMessageBundle(String resourceClasspath);
|
||||||
|
|
||||||
|
public void undeployMessageBundle(String bundleBaseName);
|
||||||
|
|
||||||
|
public void reloadMessageBundle(String bundleBaseName);
|
||||||
|
|
||||||
|
}
|
741
source/java/org/alfresco/repo/admin/RepoAdminServiceImpl.java
Executable file
741
source/java/org/alfresco/repo/admin/RepoAdminServiceImpl.java
Executable file
@ -0,0 +1,741 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.admin;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
|
import org.alfresco.model.ApplicationModel;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
|
import org.alfresco.repo.dictionary.DictionaryDAO;
|
||||||
|
import org.alfresco.repo.dictionary.M2Model;
|
||||||
|
import org.alfresco.repo.dictionary.RepositoryLocation;
|
||||||
|
import org.alfresco.repo.i18n.MessageService;
|
||||||
|
import org.alfresco.service.cmr.admin.RepoAdminService;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.ParameterCheck;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repository Admin Service Implementation.
|
||||||
|
* <p>
|
||||||
|
* @see RepoAdminService interface
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class RepoAdminServiceImpl implements RepoAdminService
|
||||||
|
{
|
||||||
|
// Logging support
|
||||||
|
private static Log logger = LogFactory.getLog("org.alfresco.repo.admin.RepoAdminServiceImpl");
|
||||||
|
|
||||||
|
// dependencies
|
||||||
|
private DictionaryDAO dictionaryDAO;
|
||||||
|
private SearchService searchService;
|
||||||
|
private NodeService nodeService;
|
||||||
|
private ContentService contentService;
|
||||||
|
private NamespaceService namespaceService;
|
||||||
|
private MessageService messageService;
|
||||||
|
|
||||||
|
private RepositoryLocation repoModelsLocation;
|
||||||
|
private RepositoryLocation repoMessagesLocation;
|
||||||
|
|
||||||
|
public final static String CRITERIA_ALL = "/*"; // immediate children only
|
||||||
|
|
||||||
|
public final static String defaultSubtypeOfDictionaryModel = "subtypeOf('cm:dictionaryModel')";
|
||||||
|
public final static String defaultSubtypeOfContent = "subtypeOf('cm:content')";
|
||||||
|
|
||||||
|
|
||||||
|
public void setDictionaryDAO(DictionaryDAO dictionaryDAO)
|
||||||
|
{
|
||||||
|
this.dictionaryDAO = dictionaryDAO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchService(SearchService searchService)
|
||||||
|
{
|
||||||
|
this.searchService = searchService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentService(ContentService contentService)
|
||||||
|
{
|
||||||
|
this.contentService = contentService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNamespaceService(NamespaceService namespaceService)
|
||||||
|
{
|
||||||
|
this.namespaceService = namespaceService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setmessageService(MessageService messageService)
|
||||||
|
{
|
||||||
|
this.messageService = messageService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setRepositoryModelsLocation(RepositoryLocation repoModelsLocation)
|
||||||
|
{
|
||||||
|
this.repoModelsLocation = repoModelsLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepositoryMessagesLocation(RepositoryLocation repoMessagesLocation)
|
||||||
|
{
|
||||||
|
this.repoMessagesLocation = repoMessagesLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.admin.RepoAdminService#getModels()
|
||||||
|
*/
|
||||||
|
public List<RepoModelDefinition> getModels()
|
||||||
|
{
|
||||||
|
StoreRef storeRef = repoModelsLocation.getStoreRef();
|
||||||
|
NodeRef rootNode = nodeService.getRootNode(storeRef);
|
||||||
|
|
||||||
|
Collection<QName> models = dictionaryDAO.getModels();
|
||||||
|
|
||||||
|
List<String> dictionaryModels = new ArrayList<String>();
|
||||||
|
for (QName model : models)
|
||||||
|
{
|
||||||
|
dictionaryModels.add(model.toPrefixString());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoModelsLocation.getPath()+CRITERIA_ALL+"["+defaultSubtypeOfDictionaryModel+"]", null, namespaceService, false);
|
||||||
|
|
||||||
|
List<RepoModelDefinition> modelsInRepo = new ArrayList<RepoModelDefinition>();
|
||||||
|
|
||||||
|
if (nodeRefs.size() > 0)
|
||||||
|
{
|
||||||
|
for (NodeRef nodeRef : nodeRefs)
|
||||||
|
{
|
||||||
|
String modelFileName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||||
|
String repoVersion = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL);
|
||||||
|
|
||||||
|
String modelName = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ContentReader cr = contentService.getReader(nodeRefs.get(0), ContentModel.TYPE_CONTENT);
|
||||||
|
InputStream is = cr.getContentInputStream();
|
||||||
|
|
||||||
|
M2Model model = M2Model.createModel(is);
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
modelName = model.getName();
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Failed to getModels " + t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check against models loaded in dictionary and give warning if not found
|
||||||
|
if (dictionaryModels.contains(modelName))
|
||||||
|
{
|
||||||
|
// note: uses dictionary model cache, rather than getting content from repo and re-compiling
|
||||||
|
modelsInRepo.add(new RepoModelDefinition(modelFileName, repoVersion, dictionaryDAO.getModel(QName.createQName(modelName, namespaceService)), true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modelsInRepo.add(new RepoModelDefinition(modelFileName, repoVersion, null, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelsInRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.admin.RepoAdminService#deployModel(java.io.InputStream, java.lang.String)
|
||||||
|
*/
|
||||||
|
public QName deployModel(InputStream modelStream, String modelFileName)
|
||||||
|
{
|
||||||
|
// Check that all the passed values are not null
|
||||||
|
ParameterCheck.mandatory("ModelStream", modelStream);
|
||||||
|
ParameterCheck.mandatoryString("ModelFileName", modelFileName);
|
||||||
|
|
||||||
|
QName modelName = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// TODO workaround due to issue with model.toXML() - see below
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(modelStream));
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
String line = null;
|
||||||
|
while ((line = in.readLine()) != null) {
|
||||||
|
buffer.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream is = new ByteArrayInputStream(buffer.toString().getBytes());
|
||||||
|
|
||||||
|
M2Model model = M2Model.createModel(is);
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
|
||||||
|
contentProps.put(ContentModel.PROP_NAME, modelFileName);
|
||||||
|
|
||||||
|
StoreRef storeRef = repoModelsLocation.getStoreRef();
|
||||||
|
NodeRef rootNode = nodeService.getRootNode(storeRef);
|
||||||
|
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoModelsLocation.getPath(), null, namespaceService, false);
|
||||||
|
|
||||||
|
if (nodeRefs.size() == 0)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Could not find custom models location " + repoModelsLocation.getPath());
|
||||||
|
}
|
||||||
|
else if (nodeRefs.size() > 1)
|
||||||
|
{
|
||||||
|
// unexpected: should not find multiple nodes with same name
|
||||||
|
throw new AlfrescoRuntimeException("Found multiple custom models location " + repoModelsLocation.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef customModelsNodeRef = nodeRefs.get(0);
|
||||||
|
|
||||||
|
nodeRefs = searchService.selectNodes(customModelsNodeRef, "*[@cm:name='"+modelFileName+"' and "+defaultSubtypeOfDictionaryModel+"]", null, namespaceService, false);
|
||||||
|
|
||||||
|
if (nodeRefs.size() == 1)
|
||||||
|
{
|
||||||
|
// re-deploy existing model to the repository
|
||||||
|
|
||||||
|
NodeRef modelNodeRef = nodeRefs.get(0);
|
||||||
|
|
||||||
|
ContentWriter writer = contentService.getWriter(modelNodeRef, ContentModel.PROP_CONTENT, true);
|
||||||
|
|
||||||
|
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
|
||||||
|
writer.setEncoding("UTF-8");
|
||||||
|
|
||||||
|
is = new ByteArrayInputStream(buffer.toString().getBytes());
|
||||||
|
writer.putContent(is); // also invokes policies for DictionaryModelType - e.g. onContentUpdate
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
/* TODO
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
model.toXML(out); // fails with NPE in JIBX - see also: http://issues.alfresco.com/browse/AR-1304
|
||||||
|
writer.putContent(out.toString("UTF-8"));
|
||||||
|
*/
|
||||||
|
|
||||||
|
// parse and update model in the dictionary
|
||||||
|
modelName = dictionaryDAO.putModel(model);
|
||||||
|
|
||||||
|
logger.info("Model re-deployed: " + modelName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// deploy new model to the repository
|
||||||
|
|
||||||
|
// note: dictionary model type has associated policies that will be invoked
|
||||||
|
ChildAssociationRef association = nodeService.createNode(customModelsNodeRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, modelFileName),
|
||||||
|
ContentModel.TYPE_DICTIONARY_MODEL,
|
||||||
|
contentProps); // also invokes policies for DictionaryModelType - e.g. onUpdateProperties
|
||||||
|
|
||||||
|
NodeRef content = association.getChildRef();
|
||||||
|
|
||||||
|
// add titled aspect (for Web Client display)
|
||||||
|
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>();
|
||||||
|
titledProps.put(ContentModel.PROP_TITLE, modelFileName);
|
||||||
|
titledProps.put(ContentModel.PROP_DESCRIPTION, modelFileName);
|
||||||
|
nodeService.addAspect(content, ContentModel.ASPECT_TITLED, titledProps);
|
||||||
|
|
||||||
|
// add versionable aspect (set auto-version)
|
||||||
|
Map<QName, Serializable> versionProps = new HashMap<QName, Serializable>();
|
||||||
|
versionProps.put(ContentModel.PROP_AUTO_VERSION, true);
|
||||||
|
nodeService.addAspect(content, ContentModel.ASPECT_VERSIONABLE, versionProps);
|
||||||
|
|
||||||
|
ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true);
|
||||||
|
|
||||||
|
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
|
||||||
|
writer.setEncoding("UTF-8");
|
||||||
|
|
||||||
|
is = new ByteArrayInputStream(buffer.toString().getBytes());
|
||||||
|
writer.putContent(is); // also invokes policies for DictionaryModelType - e.g. onContentUpdate
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
/* TODO
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
model.toXML(out); // fails with NPE in JIBX - see also: http://issues.alfresco.com/browse/AR-1304
|
||||||
|
writer.putContent(out.toString("UTF-8"));
|
||||||
|
*/
|
||||||
|
|
||||||
|
// parse and add model to dictionary
|
||||||
|
modelName = dictionaryDAO.putModel(model);
|
||||||
|
|
||||||
|
logger.info("Model deployed: " + modelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Model deployment failed", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.admin.RepoAdminService#reloadModel(java.lang.String)
|
||||||
|
*/
|
||||||
|
public QName reloadModel(String modelFileName)
|
||||||
|
{
|
||||||
|
// Check that all the passed values are not null
|
||||||
|
ParameterCheck.mandatoryString("modelFileName", modelFileName);
|
||||||
|
|
||||||
|
QName modelQName = null;
|
||||||
|
|
||||||
|
StoreRef storeRef = repoModelsLocation.getStoreRef();
|
||||||
|
NodeRef rootNode = nodeService.getRootNode(storeRef);
|
||||||
|
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoModelsLocation.getPath()+"//.[@cm:name='"+modelFileName+"' and "+defaultSubtypeOfDictionaryModel+"]", null, namespaceService, false);
|
||||||
|
|
||||||
|
if (nodeRefs.size() == 0)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Could not find custom model " + modelFileName);
|
||||||
|
}
|
||||||
|
else if (nodeRefs.size() > 1)
|
||||||
|
{
|
||||||
|
// unexpected: should not find multiple nodes with same name
|
||||||
|
throw new AlfrescoRuntimeException("Found multiple custom models " + modelFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef modelNodeRef = nodeRefs.get(0);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ContentReader cr = contentService.getReader(modelNodeRef, ContentModel.TYPE_CONTENT);
|
||||||
|
InputStream is = cr.getContentInputStream();
|
||||||
|
|
||||||
|
// create model
|
||||||
|
M2Model model = M2Model.createModel(is);
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
if (model != null)
|
||||||
|
{
|
||||||
|
String modelName = model.getName();
|
||||||
|
|
||||||
|
// parse and update model in the dictionary
|
||||||
|
modelQName = dictionaryDAO.putModel(model);
|
||||||
|
|
||||||
|
logger.info("Model loaded: " + modelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Model deployment failed", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelQName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.admin.RepoAdminService#undeployModel(java.lang.String)
|
||||||
|
*/
|
||||||
|
public QName undeployModel(String modelFileName)
|
||||||
|
{
|
||||||
|
// Check that all the passed values are not null
|
||||||
|
ParameterCheck.mandatory("modelFileName", modelFileName);
|
||||||
|
|
||||||
|
QName modelQName = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// find model in repository
|
||||||
|
|
||||||
|
StoreRef storeRef = repoModelsLocation.getStoreRef();
|
||||||
|
NodeRef rootNode = nodeService.getRootNode(storeRef);
|
||||||
|
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoModelsLocation.getPath()+"//.[@cm:name='"+modelFileName+"' and "+defaultSubtypeOfDictionaryModel+"]", null, namespaceService, false);
|
||||||
|
|
||||||
|
if (nodeRefs.size() == 0)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Could not find custom model " + modelFileName);
|
||||||
|
}
|
||||||
|
else if (nodeRefs.size() > 1)
|
||||||
|
{
|
||||||
|
// unexpected: should not find multiple nodes with same name
|
||||||
|
throw new AlfrescoRuntimeException("Found multiple custom models " + modelFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef modelNodeRef = nodeRefs.get(0);
|
||||||
|
|
||||||
|
String modelName = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ContentReader cr = contentService.getReader(modelNodeRef, ContentModel.TYPE_CONTENT);
|
||||||
|
InputStream is = cr.getContentInputStream();
|
||||||
|
|
||||||
|
M2Model model = M2Model.createModel(is);
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
modelName = model.getName();
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Failed to get model " + t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// permanently remove model from repository
|
||||||
|
nodeService.addAspect(modelNodeRef, ContentModel.ASPECT_TEMPORARY, null);
|
||||||
|
nodeService.deleteNode(modelNodeRef);
|
||||||
|
|
||||||
|
modelQName = QName.createQName(modelName, namespaceService);
|
||||||
|
|
||||||
|
dictionaryDAO.removeModel(modelQName);
|
||||||
|
|
||||||
|
logger.info("Model undeployed: " + modelFileName);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Model undeployment failed", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return modelQName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.admin.RepoAdminService#getMessageBundles()
|
||||||
|
*/
|
||||||
|
public List<String> getMessageBundles()
|
||||||
|
{
|
||||||
|
StoreRef storeRef = repoMessagesLocation.getStoreRef();
|
||||||
|
NodeRef rootNode = nodeService.getRootNode(storeRef);
|
||||||
|
|
||||||
|
Collection<String> registeredBundles = messageService.getRegisteredBundles();
|
||||||
|
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoMessagesLocation.getPath()+CRITERIA_ALL+"["+defaultSubtypeOfContent+"]", null, namespaceService, false);
|
||||||
|
|
||||||
|
List<String> resourceBundlesInRepo = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (NodeRef nodeRef : nodeRefs)
|
||||||
|
{
|
||||||
|
String resourceName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||||
|
String resourceBundleBaseName = null;
|
||||||
|
int idx1 = resourceName.indexOf("_");
|
||||||
|
if (idx1 > 0)
|
||||||
|
{
|
||||||
|
resourceBundleBaseName = resourceName.substring(0, idx1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int idx2 = resourceName.indexOf(".");
|
||||||
|
if (idx2 > 0)
|
||||||
|
{
|
||||||
|
resourceBundleBaseName = resourceName.substring(0, idx2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unexpected format
|
||||||
|
logger.warn("Unexpected message resource name: " + resourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registeredBundles != null)
|
||||||
|
{
|
||||||
|
for (String registeredBundlePath : registeredBundles)
|
||||||
|
{
|
||||||
|
if (registeredBundlePath.endsWith(resourceBundleBaseName) && (! resourceBundlesInRepo.contains(resourceBundleBaseName)))
|
||||||
|
{
|
||||||
|
resourceBundlesInRepo.add(resourceBundleBaseName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// unexpected
|
||||||
|
logger.error("Message bundle not registered: " + resourceBundleBaseName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceBundlesInRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.admin.RepoAdminService#deployMessageBundle(java.lang.String)
|
||||||
|
*/
|
||||||
|
public String deployMessageBundle(String resourceClasspath)
|
||||||
|
{
|
||||||
|
// Check that all the passed values are not null
|
||||||
|
ParameterCheck.mandatory("ResourceClasspath", resourceClasspath);
|
||||||
|
|
||||||
|
String bundleBaseName = null;
|
||||||
|
|
||||||
|
// note: resource path should be in form path1/path2/path3/bundlebasename
|
||||||
|
int idx = resourceClasspath.lastIndexOf("/");
|
||||||
|
|
||||||
|
if ((idx != -1) && (idx < (resourceClasspath.length()-1)))
|
||||||
|
{
|
||||||
|
bundleBaseName = resourceClasspath.substring(idx+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bundleBaseName == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Message deployment failed - missing bundle base name (path = " + resourceClasspath + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bundleBaseName.indexOf("_") != -1)
|
||||||
|
{
|
||||||
|
// currently limited due to parser in DictionaryRepositoryBootstrap
|
||||||
|
throw new AlfrescoRuntimeException("Message deployment failed - bundle base name '" + bundleBaseName + "' should not contain '_' (underscore)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bundleBaseName.indexOf(".") != -1)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Message deployment failed - bundle base name '" + bundleBaseName + "' should not contain '.' (period)");
|
||||||
|
}
|
||||||
|
|
||||||
|
String pattern = "classpath*:" + resourceClasspath + "*.properties";
|
||||||
|
|
||||||
|
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Resource[] resources = resolver.getResources(pattern);
|
||||||
|
|
||||||
|
if ((resources != null) && (resources.length > 0))
|
||||||
|
{
|
||||||
|
ArrayList<String> names = new ArrayList<String>();
|
||||||
|
ArrayList<Resource> filteredResources = new ArrayList<Resource>();
|
||||||
|
|
||||||
|
for (int i = 0; i < resources.length; i++)
|
||||||
|
{
|
||||||
|
String filename = resources[i].getFilename();
|
||||||
|
if (! names.contains(filename))
|
||||||
|
{
|
||||||
|
names.add(filename);
|
||||||
|
filteredResources.add(resources[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Resource resource : filteredResources)
|
||||||
|
{
|
||||||
|
InputStream fileStream = resource.getInputStream();
|
||||||
|
String filename = resource.getFilename();
|
||||||
|
deployMessageResourceFile(resourceClasspath, filename, fileStream, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// register bundle
|
||||||
|
|
||||||
|
StoreRef storeRef = repoMessagesLocation.getStoreRef();
|
||||||
|
String repoBundlePath = storeRef.toString() + repoMessagesLocation.getPath() + "/cm:" + bundleBaseName;
|
||||||
|
messageService.registerResourceBundle(repoBundlePath);
|
||||||
|
|
||||||
|
logger.info("Message resource bundle deployed: " + bundleBaseName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.warn("No message resources found: " + resourceClasspath);
|
||||||
|
throw new AlfrescoRuntimeException("No message resources found: " + resourceClasspath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Message resource bundle deployment failed ", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bundleBaseName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deploy message resource file
|
||||||
|
*/
|
||||||
|
private void deployMessageResourceFile(String bundleBasePath, String name, InputStream resourceStream, boolean registerResourceBundle)
|
||||||
|
{
|
||||||
|
// Check that all the passed values are not null
|
||||||
|
ParameterCheck.mandatory("BundleBasePath", bundleBasePath);
|
||||||
|
ParameterCheck.mandatory("Name", name);
|
||||||
|
ParameterCheck.mandatory("ResourceStream", resourceStream);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
|
||||||
|
contentProps.put(ContentModel.PROP_NAME, name);
|
||||||
|
|
||||||
|
StoreRef storeRef = repoMessagesLocation.getStoreRef();
|
||||||
|
NodeRef rootNode = nodeService.getRootNode(storeRef);
|
||||||
|
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoMessagesLocation.getPath(), null, namespaceService, false);
|
||||||
|
|
||||||
|
if (nodeRefs.size() == 0)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Could not find custom labels location " + repoMessagesLocation.getPath());
|
||||||
|
}
|
||||||
|
else if (nodeRefs.size() > 1)
|
||||||
|
{
|
||||||
|
// unexpected: should not find multiple nodes with same name
|
||||||
|
throw new AlfrescoRuntimeException("Found multiple custom labels location " + repoMessagesLocation.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef customLabelsNodeRef = nodeRefs.get(0);
|
||||||
|
|
||||||
|
ChildAssociationRef association = nodeService.createNode(customLabelsNodeRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name),
|
||||||
|
ContentModel.TYPE_CONTENT,
|
||||||
|
contentProps);
|
||||||
|
|
||||||
|
NodeRef content = association.getChildRef();
|
||||||
|
|
||||||
|
// add titled aspect (for Web Client display)
|
||||||
|
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>();
|
||||||
|
titledProps.put(ContentModel.PROP_TITLE, name);
|
||||||
|
titledProps.put(ContentModel.PROP_DESCRIPTION, name);
|
||||||
|
nodeService.addAspect(content, ContentModel.ASPECT_TITLED, titledProps);
|
||||||
|
|
||||||
|
// add inline-editable aspect
|
||||||
|
Map<QName, Serializable> editProps = new HashMap<QName, Serializable>(1, 1.0f);
|
||||||
|
editProps.put(ApplicationModel.PROP_EDITINLINE, true);
|
||||||
|
nodeService.addAspect(content, ApplicationModel.ASPECT_INLINEEDITABLE, editProps);
|
||||||
|
|
||||||
|
ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true);
|
||||||
|
|
||||||
|
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||||
|
writer.setEncoding("UTF-8");
|
||||||
|
|
||||||
|
writer.putContent(resourceStream);
|
||||||
|
resourceStream.close();
|
||||||
|
|
||||||
|
if (registerResourceBundle == true)
|
||||||
|
{
|
||||||
|
String bundleBaseName = null;
|
||||||
|
int idx = bundleBasePath.lastIndexOf("/");
|
||||||
|
if ((idx != -1) && (idx != bundleBasePath.length() - 1))
|
||||||
|
{
|
||||||
|
bundleBaseName = bundleBasePath.substring(idx+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bundleBaseName = bundleBasePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
String repoBundlePath = storeRef.toString() + repoMessagesLocation.getPath() + "/cm:" + bundleBaseName;
|
||||||
|
messageService.registerResourceBundle(repoBundlePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Message resource deployed: " + name);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Message resource deployment failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.admin.RepoAdminService#undeployMessageBundle(java.lang.String)
|
||||||
|
*/
|
||||||
|
public void undeployMessageBundle(String bundleBaseName)
|
||||||
|
{
|
||||||
|
// Check that all the passed values are not null
|
||||||
|
ParameterCheck.mandatory("bundleBaseName", bundleBaseName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StoreRef storeRef = repoMessagesLocation.getStoreRef();
|
||||||
|
|
||||||
|
// unregister bundle
|
||||||
|
String repoBundlePath = storeRef.toString() + repoMessagesLocation.getPath() + "/cm:" + bundleBaseName;
|
||||||
|
messageService.unregisterResourceBundle(repoBundlePath);
|
||||||
|
|
||||||
|
NodeRef rootNode = nodeService.getRootNode(storeRef);
|
||||||
|
|
||||||
|
List<NodeRef> nodeRefs = searchService.selectNodes(rootNode, repoMessagesLocation.getPath()+CRITERIA_ALL, null, namespaceService, false);
|
||||||
|
|
||||||
|
for (NodeRef nodeRef : nodeRefs)
|
||||||
|
{
|
||||||
|
String customLabelName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||||
|
|
||||||
|
if (customLabelName.startsWith(bundleBaseName))
|
||||||
|
{
|
||||||
|
// remove message resource file from the repository
|
||||||
|
nodeService.deleteNode(nodeRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Message resources undeployed: " + bundleBaseName);
|
||||||
|
}
|
||||||
|
catch (Throwable t)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Messages undeployment failed ", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.service.cmr.admin.RepoAdminService#reloadMessageBundle(java.lang.String)
|
||||||
|
*/
|
||||||
|
public void reloadMessageBundle(String bundleBaseName)
|
||||||
|
{
|
||||||
|
// Check that all the passed values are not null
|
||||||
|
ParameterCheck.mandatory("bundleBaseName", bundleBaseName);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
StoreRef storeRef = repoMessagesLocation.getStoreRef();
|
||||||
|
|
||||||
|
// re-register bundle
|
||||||
|
|
||||||
|
String repoBundlePath = storeRef.toString() + repoMessagesLocation.getPath() + "/cm:" + bundleBaseName;
|
||||||
|
|
||||||
|
messageService.unregisterResourceBundle(repoBundlePath);
|
||||||
|
messageService.registerResourceBundle(repoBundlePath);
|
||||||
|
|
||||||
|
logger.info("Message resources re-loaded: " + bundleBaseName);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Message resource re-load failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
source/java/org/alfresco/repo/admin/RepoModelDefinition.java
Executable file
87
source/java/org/alfresco/repo/admin/RepoModelDefinition.java
Executable file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.admin;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.dictionary.ModelDefinition;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repository-stored Model Definition
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RepoModelDefinition
|
||||||
|
{
|
||||||
|
private String repoName;
|
||||||
|
private String repoVersion;
|
||||||
|
private ModelDefinition model;
|
||||||
|
|
||||||
|
private boolean loaded;
|
||||||
|
|
||||||
|
RepoModelDefinition(String repoName, String repoVersion, ModelDefinition model, boolean loaded)
|
||||||
|
{
|
||||||
|
this.repoName = repoName;
|
||||||
|
this.repoVersion = repoVersion;
|
||||||
|
this.model = model;
|
||||||
|
this.loaded = loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getRepoName()
|
||||||
|
{
|
||||||
|
return repoName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRepoVersion()
|
||||||
|
{
|
||||||
|
return repoVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelDefinition getModel()
|
||||||
|
{
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
// JanV - temp
|
||||||
|
public boolean isLoaded()
|
||||||
|
{
|
||||||
|
return loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append("IsLoaded: " + (loaded ? "Y" : "N") + " , ");
|
||||||
|
sb.append("RepoVersion: " + repoVersion + " , ");
|
||||||
|
sb.append("RepoName: " + repoName + " , ");
|
||||||
|
sb.append("ModelQName: " + (model == null ? "n/a" : model.getName()) + " , ");
|
||||||
|
sb.append("Description: " + (model == null ? "n/a" : model.getDescription()) + " , ");
|
||||||
|
sb.append("Author: " + (model == null ? "n/a" : model.getAuthor()) + " , ");
|
||||||
|
sb.append("Published: " + (model == null ? "n/a" : model.getPublishedDate()) + " , ");
|
||||||
|
sb.append("Version: " + (model == null ? "n/a" : model.getVersion()));
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
117
source/java/org/alfresco/service/cmr/admin/RepoAdminService.java
Executable file
117
source/java/org/alfresco/service/cmr/admin/RepoAdminService.java
Executable file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
* As a special exception to the terms and conditions of version 2.0 of
|
||||||
|
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||||
|
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||||
|
* FLOSS exception. You should have recieved a copy of the text describing
|
||||||
|
* the FLOSS exception, and it is also available here:
|
||||||
|
* http://www.alfresco.com/legal/licensing"
|
||||||
|
*/
|
||||||
|
package org.alfresco.service.cmr.admin;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.repo.admin.RepoModelDefinition;
|
||||||
|
import org.alfresco.service.Auditable;
|
||||||
|
import org.alfresco.service.PublicService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repository Admin Service.
|
||||||
|
*
|
||||||
|
* Client facing API for interacting with Alfresco Repository Admin services.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@PublicService
|
||||||
|
public interface RepoAdminService
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Custom Model Management
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of deployed custom models
|
||||||
|
*
|
||||||
|
* - those that are runtime/repo managed only
|
||||||
|
*/
|
||||||
|
@Auditable
|
||||||
|
public List<RepoModelDefinition> getModels();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deploy custom model
|
||||||
|
*
|
||||||
|
* - allows creation of new models
|
||||||
|
* - allows update of existing models (*)
|
||||||
|
*
|
||||||
|
* (*) TODO - currently no validation (or locking) so can break existing usages
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Auditable(parameters = {"modelStream, modelFileName"})
|
||||||
|
public QName deployModel(InputStream modelStream, String modelFileName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undeploy custom model
|
||||||
|
*
|
||||||
|
* - allows delete of existing models (*)
|
||||||
|
* - permanently removes definition from repository (all versions)
|
||||||
|
*
|
||||||
|
* (*) TODO - currently no validation (or locking) so can break existing usages
|
||||||
|
*/
|
||||||
|
@Auditable(parameters = {"modelFileName"})
|
||||||
|
public QName undeployModel(String modelFileName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload custom model
|
||||||
|
*/
|
||||||
|
@Auditable(parameters = {"modelFileName"})
|
||||||
|
public QName reloadModel(String modelFileName);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Custom Message Management
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get deployed custom messages resource bundles
|
||||||
|
*
|
||||||
|
* - those that are runtime/repo managed only
|
||||||
|
*/
|
||||||
|
@Auditable
|
||||||
|
public List<String> getMessageBundles();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deploy custom message resource bundle
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Auditable(parameters = {"resourceClasspath"})
|
||||||
|
public String deployMessageBundle(String resourceClasspath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undeploy custom message resource bundle
|
||||||
|
*/
|
||||||
|
@Auditable(parameters = {"bundleBaseName"})
|
||||||
|
public void undeployMessageBundle(String bundleBaseName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload custom message resource bundle
|
||||||
|
*/
|
||||||
|
@Auditable(parameters = {"bundleBaseName"})
|
||||||
|
public void reloadMessageBundle(String bundleBaseName);
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user