Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/AccessManagerConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/AccessManagerConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/AccessManagerConf.java (revision 0) @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.core.config.AccessManagerConfig; +import org.apache.jackrabbit.core.security.SimpleAccessManager; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; + +public class AccessManagerConf extends BeanConf { + + public AccessManagerConf(BeanConf beanConf) { + super(beanConf); + } + + /** + * Uses {@link SimpleAccessManager} by default. + */ + public AccessManagerConf() { + this.className = SimpleAccessManager.class.getName(); + //addParameter("config", "${" + Xml.REPOSITORY_HOME_VARIABLE + "}/access.xml"); + } + + public AccessManagerConfig createAccessManagerConfig(Variables variables) throws ConfException { + return new AccessManagerConfig(super.createBeanConfig(variables)); + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[AccessManager"); + + printBeanConf(pp); + + pp.printlnIndent("]"); + } +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/BeanConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/BeanConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/BeanConf.java (revision 0) @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import java.util.Enumeration; +import java.util.Properties; + +import org.apache.jackrabbit.core.config.BeanConfig; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; + +public class BeanConf { + + protected String className; + + protected Properties parameters; + + public BeanConf() { + this.className = ""; + this.parameters = new Properties(); + } + + public BeanConf(String className, Properties parameters) { + this.className = className; + this.parameters = parameters; + } + + public BeanConf(BeanConf config) { + this(config.getClassName(), config.getParameters()); + } + + public BeanConfig createBeanConfig(Variables variables) throws ConfException { + return new BeanConfig(getClassName(), variables.replaceVariables(getParameters())); + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + public Properties getParameters() { + return parameters; + } + + public void setParameters(Properties params) { + this.parameters = params; + } + + public void setParameter(String name, String value) { + this.parameters.setProperty(name, value); + } + + public void printBeanConf(PrettyPrinter pp) { + pp.increaseIndent(); + + pp.printlnIndent("className=" + className); + for (Enumeration keys = parameters.keys(); keys.hasMoreElements();) { + String key = (String) keys.nextElement(); + pp.printlnIndent(key + "=" + parameters.getProperty(key)); + } + + pp.decreaseIndent(); + } +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/ClusterConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/ClusterConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/ClusterConf.java (revision 0) @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.core.config.ClusterConfig; +import org.apache.jackrabbit.core.config.JournalConfig; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; + +public class ClusterConf { + + private String id; + + private long syncDelay; + + private JournalConf jc; + + public ClusterConf(String id, long syncDelay, JournalConf jc) { + this.id = id; + this.syncDelay = syncDelay; + this.jc = jc; + } + + public ClusterConfig createClusterConfig(Variables variables) throws ConfException { + JournalConfig jc = null; + if (getJournalConf() != null) { + jc = getJournalConf().createJournalConfig(variables); + } + return new ClusterConfig(getId(), getSyncDelay(), jc); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public long getSyncDelay() { + return syncDelay; + } + + public void setSyncDelay(long syncDelay) { + this.syncDelay = syncDelay; + } + + public JournalConf getJournalConf() { + return jc; + } + + public void setJournalConf(JournalConf jc) { + this.jc = jc; + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[Cluster"); + + pp.increaseIndent(); + + pp.printlnIndent("id=" + id); + pp.printlnIndent("syncDelay=" + syncDelay); + + if (jc != null) jc.print(pp); + + pp.decreaseIndent(); + + pp.printlnIndent("]"); + } +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/DynamicConfigTest.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/DynamicConfigTest.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/DynamicConfigTest.java (revision 0) @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jackrabbit.test.config; + +import junit.framework.TestCase; + +import org.apache.jackrabbit.core.TransientRepository; +import org.apache.jackrabbit.core.config.RepositoryConfig; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.xml.ConfException; +import org.apache.jackrabbit.test.config.xml.RepositoryConfParser; +import org.apache.jackrabbit.test.config.xml.RepositoryConfWriter; + +/** + * DynamicConfigTest ... + * + */ +public class DynamicConfigTest extends TestCase { + + private RepositoryConf conf; + + protected RepositoryConf getRepositoryConf() throws ConfException { + if (conf == null) { + conf = RepositoryConfParser.read("applications/test/repository.xml"); + } + return conf; + } + + public void testReadDynamicConfigFromXml() throws Exception { + RepositoryConf conf = getRepositoryConf(); + System.out.println(">>>>>>>>>> Config read from 'applications/test/repository.xml'"); + conf.print(new PrettyPrinter(System.out)); + System.out.println(); + } + + public void testWriteDynamicConfigBackToXml() throws Exception { + RepositoryConf conf = getRepositoryConf(); + RepositoryConfWriter.write(conf, "target/written-repository.xml"); + } + + public void testStartRepoWithDynamicConfigFromXml() throws Exception { + RepositoryConf conf = getRepositoryConf(); + + RepositoryConfig config = conf.createConfig("applications/test"); + config.init(); + TransientRepository repo = new TransientRepository(config); + repo.login(); + repo.shutdown(); + } + + public void testStartRepoWithDefaultConfig() throws Exception { + RepositoryConf conf = new RepositoryConf(); + System.out.println(">>>>>>>>>> Default config:"); + conf.print(new PrettyPrinter(System.out)); + System.out.println(); + + RepositoryConfig config = conf.createConfig("applications/test2"); + config.init(); + TransientRepository repo = new TransientRepository(config); + repo.login(); + repo.shutdown(); + } +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/DynamicRepositoryHelper.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/DynamicRepositoryHelper.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/DynamicRepositoryHelper.java (revision 0) @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jackrabbit.test.config; + +import java.io.IOException; + +import javax.jcr.Credentials; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +import org.apache.jackrabbit.core.TransientRepository; +import org.apache.jackrabbit.core.config.RepositoryConfig; +import org.apache.jackrabbit.test.RepositoryHelper; + +/** + * DynamicRepositoryHelper ... + * + */ +public class DynamicRepositoryHelper extends RepositoryHelper { + + private TransientRepository repo; + + private RepositoryConf conf; + + private String home; + + private SimpleCredentials superuser; + + private SimpleCredentials readwrite; + + private SimpleCredentials readonly; + + public static RepositoryConf getSimpleRepositoryConf() { + RepositoryConf conf = new RepositoryConf(); + return conf; + } + + public DynamicRepositoryHelper(RepositoryConf conf, String home) { + this.conf = conf; + this.home = home; + + superuser = new SimpleCredentials("superuser", "".toCharArray()); + readwrite = new SimpleCredentials("user", "".toCharArray()); + readonly = new SimpleCredentials("anonymous", "".toCharArray()); + } + + public Repository getRepository() throws RepositoryException { + if (repo == null) { + RepositoryConfig config = conf.createConfig(home); + config.init(); + try { + repo = new TransientRepository(config); + } catch (IOException e) { + throw new RepositoryException("Cannot instantiate " + + "TransientRepository at " + home, e); + } + } + return repo; + } + + public Session getSuperuserSession(String workspaceName) + throws RepositoryException { + return getRepository().login(getSuperuserCredentials(), workspaceName); + } + + public Session getReadWriteSession(String workspaceName) + throws RepositoryException { + return getRepository().login(getReadWriteCredentials(), workspaceName); + } + + public Session getReadOnlySession(String workspaceName) + throws RepositoryException { + return getRepository().login(getReadOnlyCredentials(), workspaceName); + } + + /** + * Not implemented, always returns null. + */ + public String getProperty(String name) throws RepositoryException { + return null; + } + + public Credentials getReadOnlyCredentials() { + return readonly; + } + + public Credentials getReadWriteCredentials() { + return readwrite; + } + + public Credentials getSuperuserCredentials() { + return superuser; + } + + public void shutdown() { + if (repo != null) { + repo.shutdown(); + } + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/FileSystemConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/FileSystemConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/FileSystemConf.java (revision 0) @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.core.config.FileSystemConfig; +import org.apache.jackrabbit.core.fs.local.LocalFileSystem; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; + +public class FileSystemConf extends BeanConf { + + public FileSystemConf(BeanConf config) { + super(config); + } + + /** + * Uses {@link LocalFileSystem} by default. + */ + public FileSystemConf() { + this.className = LocalFileSystem.class.getName(); + } + + public FileSystemConfig createFileSystemConfig(Variables variables) throws ConfException { + return new FileSystemConfig(super.createBeanConfig(variables)); + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[FileSystem"); + + printBeanConf(pp); + + pp.printlnIndent("]"); + } +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/JournalConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/JournalConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/JournalConf.java (revision 0) @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.core.config.JournalConfig; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; + +public class JournalConf extends BeanConf { + + public JournalConf(BeanConf beanConf) { + super(beanConf); + } + + public JournalConfig createJournalConfig(Variables variables) throws ConfException { + return new JournalConfig(super.createBeanConfig(variables)); + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[Journal"); + + printBeanConf(pp); + + pp.printlnIndent("]"); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/LoginModuleConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/LoginModuleConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/LoginModuleConf.java (revision 0) @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.core.config.LoginModuleConfig; +import org.apache.jackrabbit.core.security.SimpleLoginModule; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; + +public class LoginModuleConf extends BeanConf { + + public LoginModuleConf(BeanConf beanConf) { + super(beanConf); + } + + /** + * Uses {@link SimpleLoginModule} by default. + */ + public LoginModuleConf() { + this.className = SimpleLoginModule.class.getName(); + + setParameter("anonymousId", "anonymous"); + } + + public LoginModuleConfig createLoginModuleConfig(Variables variables) throws ConfException { + return new LoginModuleConfig(super.createBeanConfig(variables)); + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[LoginModule"); + + printBeanConf(pp); + + pp.printlnIndent("]"); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/PersistenceManagerConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/PersistenceManagerConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/PersistenceManagerConf.java (revision 0) @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.core.config.PersistenceManagerConfig; +import org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; + +public class PersistenceManagerConf extends BeanConf { + + public PersistenceManagerConf(BeanConf beanConf) { + super(beanConf); + } + + /** + * Uses {@link DerbyPersistenceManager} (bundle) by default. + */ + public PersistenceManagerConf() { + this.className = DerbyPersistenceManager.class.getName(); + } + + public PersistenceManagerConfig createPersistenceManagerConfig(Variables variables) throws ConfException { + return new PersistenceManagerConfig(super.createBeanConfig(variables)); + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[PersistenceManager"); + + printBeanConf(pp); + + pp.printlnIndent("]"); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/RepositoryConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/RepositoryConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/RepositoryConf.java (revision 0) @@ -0,0 +1,265 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.core.config.ClusterConfig; +import org.apache.jackrabbit.core.config.FileSystemConfig; +import org.apache.jackrabbit.core.config.RepositoryConfig; +import org.apache.jackrabbit.core.config.RepositoryConfigurationParser; +import org.apache.jackrabbit.core.config.SearchConfig; +import org.apache.jackrabbit.core.config.SecurityConfig; +import org.apache.jackrabbit.core.config.VersioningConfig; +import org.apache.jackrabbit.core.fs.local.LocalFileSystem; +import org.apache.jackrabbit.core.persistence.bundle.DerbyPersistenceManager; +import org.apache.jackrabbit.core.query.lucene.SearchIndex; +import org.apache.jackrabbit.core.security.SimpleAccessManager; +import org.apache.jackrabbit.core.security.SimpleLoginModule; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; +import org.apache.jackrabbit.test.config.xml.RepositoryConfWriter; +import org.apache.jackrabbit.test.config.xml.Xml; + +public class RepositoryConf { + + private String home; + + private String defaultWorkspace; + + private String workspaceDirectory; + + private String workspaceConfigDirectory; + + private int workspaceMaxIdleTime; + + private SecurityConf sec; + + private FileSystemConf fsc; + + private VersioningConf vc; + + private SearchConf sc; + + private ClusterConf cc; + + private WorkspaceConf workspaceConfTemplate; + + public RepositoryConf(String home, SecurityConf securityConf, + FileSystemConf fsc, String workspaceDirectory, + String workspaceConfigDirectory, String defaultWorkspace, + int workspaceMaxIdleTime, WorkspaceConf workspaceConfTemplate, VersioningConf vc, + SearchConf sc, ClusterConf cc) { + this.home = home; + this.sec = securityConf; + this.fsc = fsc; + this.workspaceDirectory = workspaceDirectory; + this.workspaceConfigDirectory = workspaceConfigDirectory; + this.defaultWorkspace = defaultWorkspace; + this.workspaceMaxIdleTime = workspaceMaxIdleTime; + this.vc = vc; + this.sc = sc; + this.cc = cc; + this.workspaceConfTemplate = workspaceConfTemplate; + } + + /** + * The default configuration uses the bundle {@link DerbyPersistenceManager} + * (for versioning and workspaces), a {@link LocalFileSystem} (for repository, + * versioning and workspaces), a {@link SearchIndex} (for repository and + * workspaces) and a {@link SimpleAccessManager} as well as a + * {@link SimpleLoginModule} for security config. + */ + public RepositoryConf() { + this.home = "${" + Xml.REPOSITORY_HOME_VARIABLE + "}"; + + this.workspaceDirectory = this.home + "/workspaces"; + this.workspaceConfigDirectory = null; + this.workspaceMaxIdleTime = 0; + this.defaultWorkspace = "default"; + + this.sec = new SecurityConf(); + + this.fsc = new FileSystemConf(); + this.fsc.setParameter("path", this.home + "/repository"); + + this.vc = new VersioningConf(); + + this.sc = new SearchConf(); + this.sc.setParameter("path", this.home + "/repository/index"); + + this.cc = null; + this.workspaceConfTemplate = new WorkspaceConf(); + } + + /** + * Don't forget to call init() on the returned {@link RepositoryConfig}. + */ + public RepositoryConfig createConfig(String home) throws ConfException { + Variables variables = new Variables(); + variables.setProperty(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, home); + + return createConfig(variables); + } + + public RepositoryConfig createConfig(Variables variables) throws ConfException { + ClusterConfig cc = null; + if (getClusterConf() != null) { + cc = getClusterConf().createClusterConfig(variables); + } + SecurityConfig sec = null; + if (getSecurityConf() != null) { + sec = getSecurityConf().createSecurityConfig(variables); + } + FileSystemConfig fsc = null; + if (getFileSystemConf() != null) { + fsc = getFileSystemConf().createFileSystemConfig(variables); + } + VersioningConfig vc = null; + if (getVersioningConf() != null) { + vc = getVersioningConf().createVersioningConfig(variables); + } + SearchConfig sc = null; + if (getSearchConf() != null) { + sc = getSearchConf().createSearchConfig(variables); + } + return new RepositoryConfig( + variables.replaceVariables(getHomeDir()), + sec, + fsc, + variables.replaceVariables(getWorkspaceDirectory()), + getWorkspaceConfigDirectory(), + variables.replaceVariables(getDefaultWorkspaceName()), + getWorkspaceMaxIdleTime(), + RepositoryConfWriter.createWorkspaceConfElement(workspaceConfTemplate), + vc, + sc, + cc, + new RepositoryConfigurationParser(variables) + ); + } + + public String getHomeDir() { + return home; + } + + public FileSystemConf getFileSystemConf() { + return fsc; + } + + public SecurityConf getSecurityConf() { + return sec; + } + + public String getWorkspaceDirectory() { + return workspaceDirectory; + } + + public String getWorkspaceConfigDirectory() { + return workspaceConfigDirectory; + } + + public String getDefaultWorkspaceName() { + return defaultWorkspace; + } + + public int getWorkspaceMaxIdleTime() { + return workspaceMaxIdleTime; + } + + public VersioningConf getVersioningConf() { + return vc; + } + + public SearchConf getSearchConf() { + return sc; + } + + public ClusterConf getClusterConf() { + return cc; + } + + public void setHome(String home) { + this.home = home; + } + + public void setSec(SecurityConf sec) { + this.sec = sec; + } + + public void setFsc(FileSystemConf fsc) { + this.fsc = fsc; + } + + public void setDefaultWorkspace(String defaultWorkspace) { + this.defaultWorkspace = defaultWorkspace; + } + + public void setWorkspaceDirectory(String workspaceDirectory) { + this.workspaceDirectory = workspaceDirectory; + } + + public void setWorkspaceMaxIdleTime(int workspaceMaxIdleTime) { + this.workspaceMaxIdleTime = workspaceMaxIdleTime; + } + + public void setVersioningConf(VersioningConf vc) { + this.vc = vc; + } + + public void setSearchConf(SearchConf sc) { + this.sc = sc; + } + + public void setClusterConf(ClusterConf cc) { + this.cc = cc; + } + + public void setWorkspaceConfigDirectory(String workspaceConfigDirectory) { + this.workspaceConfigDirectory = workspaceConfigDirectory; + } + + public WorkspaceConf getWorkspaceConfTemplate() { + return workspaceConfTemplate; + } + + public void setWorkspaceConfTemplate(WorkspaceConf workspaceConfTemplate) { + this.workspaceConfTemplate = workspaceConfTemplate; + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[Repository"); + + pp.increaseIndent(); + + pp.printlnIndent("home=" + home + ", "); + pp.printlnIndent("defaultWorkspace=" + defaultWorkspace + ", "); + pp.printlnIndent("workspaceDirectory=" + workspaceDirectory + ", "); + pp.printlnIndent("workspaceMaxIdleTime=" + workspaceMaxIdleTime + ", "); + pp.printlnIndent("workspaceConfigDirectory=" + workspaceConfigDirectory); + + if (sec != null) sec.print(pp); + if (fsc != null) fsc.print(pp); + if (vc != null) vc.print(pp); + if (sc != null) sc.print(pp); + if (cc != null) cc.print(pp); + if (workspaceConfTemplate != null) workspaceConfTemplate.print(pp); + + pp.decreaseIndent(); + + pp.printlnIndent("]"); + } +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/SearchConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/SearchConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/SearchConf.java (revision 0) @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import java.util.Properties; + +import org.apache.jackrabbit.core.config.FileSystemConfig; +import org.apache.jackrabbit.core.config.SearchConfig; +import org.apache.jackrabbit.core.query.lucene.SearchIndex; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; + +public class SearchConf extends BeanConf { + + private FileSystemConf fsc; + + public SearchConf(String className, Properties parameters, + FileSystemConf fsc) { + super(className, parameters); + this.fsc = fsc; + } + + /** + * Uses {@link SearchIndex} by default. + */ + public SearchConf() { + this.className = SearchIndex.class.getName(); + } + + public SearchConfig createSearchConfig(Variables variables) throws ConfException { + FileSystemConfig fsc = null; + if (getFileSystemConf() != null) { + fsc = getFileSystemConf().createFileSystemConfig(variables); + } + return new SearchConfig(getClassName(), variables.replaceVariables(getParameters()), fsc); + } + + public FileSystemConf getFileSystemConf() { + return fsc; + } + + public void setFileSystemConf(FileSystemConf fsc) { + this.fsc = fsc; + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[SearchIndex"); + + printBeanConf(pp); + + pp.increaseIndent(); + + if (fsc != null) fsc.print(pp); + + pp.decreaseIndent(); + + pp.printlnIndent("]"); + } +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/SecurityConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/SecurityConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/SecurityConf.java (revision 0) @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.core.config.AccessManagerConfig; +import org.apache.jackrabbit.core.config.LoginModuleConfig; +import org.apache.jackrabbit.core.config.SecurityConfig; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; + +public class SecurityConf { + + private String appName; + + private AccessManagerConf amc; + + private LoginModuleConf lmc; + + public SecurityConf(String appName, AccessManagerConf accessManagerConf, + LoginModuleConf loginModuleConf) { + this.appName = appName; + this.amc = accessManagerConf; + this.lmc = loginModuleConf; + } + + public SecurityConf() { + this.appName = "Jackrabbit"; + + this.amc = new AccessManagerConf(); + this.lmc = new LoginModuleConf(); + } + + public SecurityConfig createSecurityConfig(Variables variables) throws ConfException { + AccessManagerConfig amc = null; + if (getAccessManagerConf() != null) { + amc = getAccessManagerConf().createAccessManagerConfig(variables); + } + LoginModuleConfig lmc = null; + if (getLoginModuleConf() != null) { + lmc = getLoginModuleConf().createLoginModuleConfig(variables); + } + return new SecurityConfig(getAppName(), amc, lmc); + } + + public String getAppName() { + return appName; + } + + public AccessManagerConf getAccessManagerConf() { + return amc; + } + + public LoginModuleConf getLoginModuleConf() { + return lmc; + } + + public void setName(String name) { + this.appName = name; + } + + public void setAccessManagerConf(AccessManagerConf amc) { + this.amc = amc; + } + + public void setLoginModuleConf(LoginModuleConf lmc) { + this.lmc = lmc; + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[Security"); + + pp.increaseIndent(); + + pp.printlnIndent("name=" + appName); + + if (amc != null) amc.print(pp); + if (lmc != null) lmc.print(pp); + + pp.decreaseIndent(); + + pp.printlnIndent("]"); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/util/PrettyPrinter.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/util/PrettyPrinter.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/util/PrettyPrinter.java (revision 0) @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jackrabbit.test.config.util; + +import java.io.OutputStream; +import java.io.PrintWriter; + +/** + * PrettyPrinter ... + * + */ +public class PrettyPrinter extends PrintWriter { + + private final int indent; + + private int currentIndent; + + private final String indentString; + + public PrettyPrinter(OutputStream out) { + super(out); + this.indent = 4; + this.indentString = " "; + } + + public PrettyPrinter(OutputStream out, int indent, String indentString) { + super(out); + this.indent = indent; + this.indentString = indentString; + } + + public void increaseIndent() { + currentIndent += indent; + } + + public void decreaseIndent() { + if ((currentIndent - indent) < 0) { + currentIndent = 0; + } else { + currentIndent -= indent; + } + } + + public void printIndent() { + for (int i=0; i < currentIndent; i++) { + print(indentString); + } + } + + public void printIndent(String s) { + printIndent(); + super.print(s); + } + + public void printlnIndent(String x) { + printIndent(); + super.println(x); + flush(); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/util/Variables.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/util/Variables.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/util/Variables.java (revision 0) @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jackrabbit.test.config.util; + +import java.util.Enumeration; +import java.util.Properties; + +import org.apache.jackrabbit.test.config.xml.ConfException; +import org.apache.jackrabbit.util.Text; + +/** + * Variables extends the standard {@link Properties} with + * a {@link #replaceVariables(String)} method that effectively calss + * {@link Text#replaceVariables(Properties, String, boolean)}. + * + */ +public class Variables extends Properties { + + private static final long serialVersionUID = 3311868957558121444L; + + public String replaceVariables(String value) throws ConfException { + try { + return Text.replaceVariables(this, value, false); + } catch (IllegalArgumentException e) { + throw new ConfException(e.getMessage()); + } + } + + /** + * Clones the given Properties and replaces variables in all values. + */ + public Properties replaceVariables(Properties properties) throws ConfException { + Properties newProps = new Properties(); + for (Enumeration keys = properties.keys(); keys.hasMoreElements();) { + String key = (String) keys.nextElement(); + newProps.setProperty(key, replaceVariables(properties.getProperty(key))); + } + return newProps; + } +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/VersioningConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/VersioningConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/VersioningConf.java (revision 0) @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.core.config.FileSystemConfig; +import org.apache.jackrabbit.core.config.PersistenceManagerConfig; +import org.apache.jackrabbit.core.config.VersioningConfig; +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.util.Variables; +import org.apache.jackrabbit.test.config.xml.ConfException; +import org.apache.jackrabbit.test.config.xml.Xml; + +public class VersioningConf { + + private String homeDir; + + private FileSystemConf fsc; + + private PersistenceManagerConf pmc; + + public VersioningConf(String homeDir, FileSystemConf fsc, + PersistenceManagerConf pmc) { + this.homeDir = homeDir; + this.fsc = fsc; + this.pmc = pmc; + } + + public VersioningConf() { + this.homeDir = "${" + Xml.REPOSITORY_HOME_VARIABLE + "}/version"; + + this.fsc = new FileSystemConf(); + this.fsc.setParameter("path", "${" + Xml.REPOSITORY_HOME_VARIABLE + "}/version"); + + this.pmc = new PersistenceManagerConf(); + this.pmc.setParameter("url", "jdbc:derby:${" + Xml.REPOSITORY_HOME_VARIABLE + "}/version/db/itemState;create=true"); + this.pmc.setParameter("schemaObjectPrefix", "version_"); + } + + public VersioningConfig createVersioningConfig(Variables variables) throws ConfException { + FileSystemConfig fsc = null; + if (getFileSystemConf() != null) { + fsc = getFileSystemConf().createFileSystemConfig(variables); + } + PersistenceManagerConfig pmc = null; + if (getPersistenceManagerConf() != null) { + pmc = getPersistenceManagerConf().createPersistenceManagerConfig(variables); + } + + return new VersioningConfig(variables.replaceVariables(getHomeDir()), fsc, pmc); + } + + public String getHomeDir() { + return homeDir; + } + + public FileSystemConf getFileSystemConf() { + return fsc; + } + + public PersistenceManagerConf getPersistenceManagerConf() { + return pmc; + } + + public void setHomeDir(String home) { + this.homeDir = home; + } + + public void setFileSystemConf(FileSystemConf fsc) { + this.fsc = fsc; + } + + public void setPersistenceManagerConf(PersistenceManagerConf pmc) { + this.pmc = pmc; + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[Versioning"); + + pp.increaseIndent(); + + pp.printlnIndent("homeDir=" + homeDir); + + if (fsc != null) fsc.print(pp); + if (pmc != null) pmc.print(pp); + + pp.decreaseIndent(); + + pp.printlnIndent("]"); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/WorkspaceConf.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/WorkspaceConf.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/WorkspaceConf.java (revision 0) @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config; + +import org.apache.jackrabbit.test.config.util.PrettyPrinter; +import org.apache.jackrabbit.test.config.xml.Xml; + +public class WorkspaceConf { + + private String name; + + private boolean clustered; + + private FileSystemConf fsc; + + private PersistenceManagerConf pmc; + + private SearchConf sc; + + public WorkspaceConf(String name, boolean clustered, + FileSystemConf fsc, PersistenceManagerConf pmc, SearchConf sc) { + this.name = name; + this.clustered = clustered; + this.fsc = fsc; + this.pmc = pmc; + this.sc = sc; + } + + public WorkspaceConf() { + this.name = "${" + Xml.WORKSPACE_NAME_VARIABLE + "}"; + this.clustered = true; + + this.fsc = new FileSystemConf(); + this.fsc.setParameter("path", "${" + Xml.WORKSPACE_HOME_VARIABLE + "}"); + + this.pmc = new PersistenceManagerConf(); + this.pmc.setParameter("url", "jdbc:derby:${" + Xml.WORKSPACE_HOME_VARIABLE + "}/db/itemState;create=true"); + this.pmc.setParameter("schemaObjectPrefix", "${" + Xml.WORKSPACE_NAME_VARIABLE + "}_"); + + this.sc = new SearchConf(); + this.sc.setParameter("path", "${" + Xml.WORKSPACE_HOME_VARIABLE + "}/index"); + } + + /** + * This method is probably never needed. + */ +// public WorkspaceConfig createWorkspaceConfig(String name, Variables parentVariables) throws ConfException { +// Variables variables = new Variables(); +// variables.putAll(parentVariables); +// variables.put(Xml.WORKSPACE_NAME_VARIABLE, name); +// +// FileSystemConfig fsc = null; +// if (getFileSystemConf() != null) { +// fsc = getFileSystemConf().createFileSystemConfig(); +// } +// PersistenceManagerConfig pmc = null; +// if (getPersistenceManagerConf() != null) { +// pmc = getPersistenceManagerConf().createPersistenceManagerConfig(); +// } +// SearchConfig sc = null; +// if (getSearchConf() != null) { +// sc = getSearchConf().createSearchConfig(); +// } +// +// return new WorkspaceConfig(variables.replaceVariables(getHome()), +// getName(), isClustered(), fsc, pmc, sc); +// } + + public String getName() { + return name; + } + + public boolean isClustered() { + return clustered; + } + + public FileSystemConf getFileSystemConf() { + return fsc; + } + + public PersistenceManagerConf getPersistenceManagerConf() { + return pmc; + } + + public SearchConf getSearchConf() { + return sc; + } + + public void setName(String name) { + this.name = name; + } + + public void setClustered(boolean clustered) { + this.clustered = clustered; + } + + public void setFileSystemConf(FileSystemConf fsc) { + this.fsc = fsc; + } + + public void setPersistenceManagerConf(PersistenceManagerConf pmc) { + this.pmc = pmc; + } + + public void setSearchConf(SearchConf sc) { + this.sc = sc; + } + + public void print(PrettyPrinter pp) { + pp.printlnIndent("[Workspace"); + + pp.increaseIndent(); + + pp.printlnIndent("name=" + name); + pp.printlnIndent("clustered=" + clustered); + + if (fsc != null) fsc.print(pp); + if (pmc != null) pmc.print(pp); + if (sc != null) sc.print(pp); + + pp.decreaseIndent(); + + pp.printlnIndent("]"); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/ConfEntityResolver.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/ConfEntityResolver.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/ConfEntityResolver.java (revision 0) @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config.xml; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * Entity resolver for Jackrabbit configuration files. + * This simple resolver contains mappings for the following + * public identifiers used for the Jackrabbit configuration files: + * + *

+ * Also the following system identifiers are mapped to local resources: + *

+ *

+ * The public identifiers are mapped to document type definition + * files included in the Jackrabbit jar archive. + */ +public class ConfEntityResolver implements EntityResolver { + + /** + * The singleton instance of this class. + */ + public static final EntityResolver INSTANCE = + new ConfEntityResolver(); + + /** + * Public identifiers. + */ + private final Map publicIds = new HashMap(); + + /** + * System identifiers. + */ + private final Map systemIds = new HashMap(); + + /** + * Creates the singleton instance of this class. + */ + private ConfEntityResolver() { + // Apache Jackrabbit 1.2 DTD + publicIds.put( + "-//The Apache Software Foundation//DTD Jackrabbit 1.2//EN", + "repository-1.2.dtd"); + systemIds.put( + "http://jackrabbit.apache.org/dtd/repository-1.2.dtd", + "repository-1.2.dtd"); + + // Apache Jackrabbit 1.0 DTD + publicIds.put( + "-//The Apache Software Foundation//DTD Jackrabbit 1.0//EN", + "repository-1.0.dtd"); + systemIds.put( + "http://jackrabbit.apache.org/dtd/repository-1.0.dtd", + "repository-1.0.dtd"); + } + + /** + * Resolves an entity to the corresponding input source. + * + * @param publicId public identifier + * @param systemId system identifier + * @return resolved entity source + * @throws SAXException on SAX errors + * @throws IOException on IO errors + */ + public InputSource resolveEntity(String publicId, String systemId) + throws SAXException, IOException { + String name; + + name = (String) publicIds.get(publicId); + if (name != null) { + InputStream stream = getClass().getResourceAsStream(name); + if (stream != null) { + return new InputSource(stream); + } + } + + name = (String) systemIds.get(systemId); + if (name != null) { + InputStream stream = getClass().getResourceAsStream(name); + if (stream != null) { + return new InputSource(stream); + } + } + + return null; + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/ConfException.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/ConfException.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/ConfException.java (revision 0) @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config.xml; + +import javax.jcr.RepositoryException; + +/** + * Exception class used for configuration errors. + */ +public class ConfException extends RepositoryException { + + private static final long serialVersionUID = -3142383451574534838L; + + /** + * Creates a configuration exception. + * + * @param message configuration message + */ + public ConfException(String message) { + super(message); + } + + /** + * Creates a configuration exception that is caused by another exception. + * + * @param message configuration error message + * @param cause root cause of the configuration error + */ + public ConfException(String message, Exception cause) { + super(message, cause); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/ConfParser.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/ConfParser.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/ConfParser.java (revision 0) @@ -0,0 +1,242 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config.xml; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.apache.jackrabbit.test.config.BeanConf; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import java.io.IOException; +import java.util.Properties; + +/** + * Configuration parser base class. This class provides the basic + * functionality for parsing Jackrabbit configuration files. Subclasses + * extend this functionality with knowledge of the exact structure of the + * different configuration files. Each configuration parser instance + * contains a set of parser variables that are used for variable replacement + * in the configuration file. + */ +public class ConfParser { + + /** Name of the bean parameter configuration element. */ + public static final String PARAM_ELEMENT = "param"; + + /** Name of the bean implementation class configuration attribute. */ + public static final String CLASS_ATTRIBUTE = "class"; + + /** Name of the bean parameter name configuration attribute. */ + public static final String NAME_ATTRIBUTE = "name"; + + /** Name of the bean parameter value configuration attribute. */ + public static final String VALUE_ATTRIBUTE = "value"; + + /** + * Parses a named bean configuration from the given element. + * Bean configuration uses the following format: + *

+     *   <BeanName class="...">
+     *     <param name="..." value="..."/>
+     *     ...
+     *   </BeanName>
+     * 
+ *

+ * The returned bean configuration object contains the configured + * class name and configuration parameters. Variable replacement + * is performed on the parameter values. + * + * @param parent parent element + * @param name name of the bean configuration element + * @return bean configuration, + * @throws ConfException if the configuration element does not + * exist or is broken + */ + protected BeanConf parseBeanConf(Element parent, String name) + throws ConfException { + // Bean configuration element + Element element = getElement(parent, name); + + // Bean implementation class + String className = getAttribute(element, CLASS_ATTRIBUTE); + + // Bean properties + Properties properties = parseParameters(element); + + return new BeanConf(className, properties); + } + + /** + * Parses the configuration parameters of the given element. + * Parameters are stored as + * <param name="..." value="..."/> + * child elements. This method parses all param elements without + * modifying parameter values, and returns the resulting name-value pairs. + * + * @param element configuration element + * @return configuration parameters + * @throws ConfException if a param element does + * not contain the name and + * value attributes + */ + protected Properties parseParameters(Element element) + throws ConfException { + Properties parameters = new Properties(); + + NodeList children = element.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE + && PARAM_ELEMENT.equals(child.getNodeName())) { + Element parameter = (Element) child; + Attr name = parameter.getAttributeNode(NAME_ATTRIBUTE); + if (name == null) { + throw new ConfException("Parameter name not set"); + } + Attr value = parameter.getAttributeNode(VALUE_ATTRIBUTE); + if (value == null) { + throw new ConfException("Parameter value not set"); + } + parameters.put(name.getValue(), value.getValue()); + } + } + + return parameters; + } + + /** + * Parses the given XML document and returns the DOM root element. + * A custom entity resolver is used to make the included configuration + * file DTD available using the specified public identifiers. + * + * @see ConfEntityResolver + * @param xml xml document + * @return root element + * @throws ConfException if the configuration document could + * not be read or parsed + */ + protected Element parseXML(InputSource xml) throws ConfException { + try { + DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + builder.setEntityResolver(ConfEntityResolver.INSTANCE); + Document document = builder.parse(xml); + return document.getDocumentElement(); + } catch (ParserConfigurationException e) { + throw new ConfException( + "Unable to create configuration XML parser", e); + } catch (SAXException e) { + throw new ConfException( + "Configuration file syntax error.", e); + } catch (IOException e) { + throw new ConfException( + "Configuration file could not be read.", e); + } + } + + /** + * Returns the named child of the given parent element. + * + * @param parent parent element + * @param name name of the child element + * @return named child element + * @throws ConfException + * @throws ConfException if the child element is not found + */ + protected Element getElement(Element parent, String name) + throws ConfException { + return getElement(parent, name, true); + } + + /** + * Returns the named child of the given parent element. + * + * @param parent parent element + * @param name name of the child element + * @param required indicates if the child element is required + * @return named child element, or null if not found and + * required is false. + * @throws ConfException if the child element is not found and + * required is true. + */ + protected Element getElement(Element parent, String name, boolean required) + throws ConfException { + NodeList children = parent.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE + && name.equals(child.getNodeName())) { + return (Element) child; + } + } + if (required) { + throw new ConfException( + "Configuration element " + name + " not found in " + + parent.getNodeName() + "."); + } else { + return null; + } + } + + /** + * Returns the value of the named attribute of the given element. + * + * @param element element + * @param name attribute name + * @return attribute value + * @throws ConfException if the attribute is not found + */ + protected String getAttribute(Element element, String name) + throws ConfException { + Attr attribute = element.getAttributeNode(name); + if (attribute != null) { + return attribute.getValue(); + } else { + throw new ConfException( + "Configuration attribute " + name + " not found in " + + element.getNodeName() + "."); + } + } + + /** + * Returns the value of the named attribute of the given element. + * If the attribute is not found, then the given default value is returned. + * + * @param element element + * @param name attribute name + * @param def default value + * @return attribute value, or the default value + */ + protected String getAttribute(Element element, String name, String def) { + Attr attribute = element.getAttributeNode(name); + if (attribute != null) { + return attribute.getValue(); + } else { + return def; + } + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/RepositoryConfParser.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/RepositoryConfParser.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/RepositoryConfParser.java (revision 0) @@ -0,0 +1,230 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.test.config.xml; + +import java.io.File; +import java.net.URI; +import java.util.Properties; + +import org.apache.jackrabbit.test.config.AccessManagerConf; +import org.apache.jackrabbit.test.config.ClusterConf; +import org.apache.jackrabbit.test.config.FileSystemConf; +import org.apache.jackrabbit.test.config.JournalConf; +import org.apache.jackrabbit.test.config.LoginModuleConf; +import org.apache.jackrabbit.test.config.PersistenceManagerConf; +import org.apache.jackrabbit.test.config.RepositoryConf; +import org.apache.jackrabbit.test.config.SearchConf; +import org.apache.jackrabbit.test.config.SecurityConf; +import org.apache.jackrabbit.test.config.VersioningConf; +import org.apache.jackrabbit.test.config.WorkspaceConf; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +public class RepositoryConfParser extends ConfParser { + + public static RepositoryConf read(String file) throws ConfException { + return read(new File(file)); + } + + public static RepositoryConf read(File file) throws ConfException { + URI uri = file.toURI(); + return read(new InputSource(uri.toString())); + } + + public static RepositoryConf read(InputSource xml) throws ConfException { + RepositoryConfParser parser = new RepositoryConfParser(); + Element root = parser.parseXML(xml); + return parser.parseRepositoryConf(root); + } + +// public static WorkspaceConf readWorkspaceConf(InputSource xml) throws ConfException { +// RepositoryConfParser parser = new RepositoryConfParser(); +// Element root = parser.parseXML(xml); +// return parser.parseWorkspaceConf(root); +// } + + protected RepositoryConf parseRepositoryConf(Element root) throws ConfException { + // Repository home directory + // (variable will be replaced later when converting RepositoryConf to RepositoryConfig) + String home = "${" + Xml.REPOSITORY_HOME_VARIABLE + "}"; + + // File system implementation + FileSystemConf fsc = + new FileSystemConf(parseBeanConf(root, Xml.FILE_SYSTEM_ELEMENT)); + + // Security Configuration and access manager implementation + Element security = getElement(root, Xml.SECURITY_ELEMENT); + SecurityConf securityConf = parseSecurityConf(security); + + // General workspace Configuration + Element workspaces = getElement(root, Xml.WORKSPACES_ELEMENT); + String workspaceDirectory = getAttribute(workspaces, Xml.ROOT_PATH_ATTRIBUTE); + + String workspaceConfDirectory = + getAttribute(workspaces, Xml.CONFIG_ROOT_PATH_ATTRIBUTE, null); + + String defaultWorkspace = getAttribute(workspaces, Xml.DEFAULT_WORKSPACE_ATTRIBUTE); + + int maxIdleTime = Integer.parseInt( + getAttribute(workspaces, Xml.MAX_IDLE_TIME_ATTRIBUTE, "0")); + + // Workspace Configuration template + WorkspaceConf wcTemplate = parseWorkspaceConf(getElement(root, Xml.WORKSPACE_ELEMENT)); + + // Versioning Configuration + VersioningConf vc = parseVersioningConf(root); + + // Optional search Configuration + SearchConf sc = parseSearchConf(root); + + // Optional journal Configuration + ClusterConf cc = parseClusterConf(root); + + return new RepositoryConf(home, securityConf, fsc, + workspaceDirectory, workspaceConfDirectory, defaultWorkspace, + maxIdleTime, wcTemplate, vc, sc, cc); + } + + protected WorkspaceConf parseWorkspaceConf(Element element) throws ConfException { + // Workspace name + String name = getAttribute(element, NAME_ATTRIBUTE); + + // Clustered attribute + boolean clustered = Boolean.valueOf( + getAttribute(element, Xml.CLUSTERED_ATTRIBUTE, "true")).booleanValue(); + + // File system implementation + FileSystemConf fsc = new FileSystemConf(parseBeanConf(element, Xml.FILE_SYSTEM_ELEMENT)); + + // Persistence manager implementation + PersistenceManagerConf pmc = parsePersistenceManagerConf(element); + + // Search implementation (optional) + SearchConf sc = parseSearchConf(element); + + return new WorkspaceConf(name, clustered, fsc, pmc, sc); + } + + protected SecurityConf parseSecurityConf(Element security) + throws ConfException { + String appName = getAttribute(security, Xml.APP_NAME_ATTRIBUTE); + AccessManagerConf amc = parseAccessManagerConf(security); + LoginModuleConf lmc = parseLoginModuleConf(security); + return new SecurityConf(appName, amc, lmc); + } + + protected AccessManagerConf parseAccessManagerConf(Element security) + throws ConfException { + return new AccessManagerConf( + parseBeanConf(security, Xml.ACCESS_MANAGER_ELEMENT)); + } + + protected LoginModuleConf parseLoginModuleConf(Element security) + throws ConfException { + // Optional login module + Element loginModule = getElement(security, Xml.LOGIN_MODULE_ELEMENT, false); + + if (loginModule != null) { + return new LoginModuleConf(parseBeanConf(security, Xml.LOGIN_MODULE_ELEMENT)); + } else { + return null; + } + } + + protected SearchConf parseSearchConf(Element parent) + throws ConfException { + NodeList children = parent.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE + && Xml.SEARCH_INDEX_ELEMENT.equals(child.getNodeName())) { + Element element = (Element) child; + + // Search implementation class + String className = getAttribute( + element, Xml.CLASS_ATTRIBUTE, Xml.DEFAULT_QUERY_HANDLER); + + // Search parameters + Properties parameters = parseParameters(element); + + // Optional file system implementation + FileSystemConf fsc = null; + if (getElement(element, Xml.FILE_SYSTEM_ELEMENT, false) != null) { + fsc = new FileSystemConf( + parseBeanConf(element, Xml.FILE_SYSTEM_ELEMENT)); + } + + return new SearchConf(className, parameters, fsc); + } + } + return null; + } + + protected VersioningConf parseVersioningConf(Element parent) + throws ConfException { + Element element = getElement(parent, Xml.VERSIONING_ELEMENT); + + // Versioning home directory + String home = getAttribute(element, Xml.ROOT_PATH_ATTRIBUTE); + + // File system implementation + FileSystemConf fsc = new FileSystemConf( + parseBeanConf(element, Xml.FILE_SYSTEM_ELEMENT)); + + // Persistence manager implementation + PersistenceManagerConf pmc = parsePersistenceManagerConf(element); + + return new VersioningConf(home, fsc, pmc); + } + + protected ClusterConf parseClusterConf(Element parent) + throws ConfException { + + NodeList children = parent.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE + && Xml.CLUSTER_ELEMENT.equals(child.getNodeName())) { + Element element = (Element) child; + + String id = getAttribute(element, Xml.ID_ATTRIBUTE, null); + long syncDelay = Long.parseLong( + getAttribute(element, Xml.SYNC_DELAY_ATTRIBUTE, Xml.DEFAULT_SYNC_DELAY)); + + JournalConf jc = parseJournalConf(element); + return new ClusterConf(id, syncDelay, jc); + } + } + return null; + } + + protected JournalConf parseJournalConf(Element cluster) + throws ConfException { + + return new JournalConf( + parseBeanConf(cluster, Xml.JOURNAL_ELEMENT)); + } + + protected PersistenceManagerConf parsePersistenceManagerConf( + Element parent) throws ConfException { + return new PersistenceManagerConf( + parseBeanConf(parent, Xml.PERSISTENCE_MANAGER_ELEMENT)); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/RepositoryConfWriter.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/RepositoryConfWriter.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/RepositoryConfWriter.java (revision 0) @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jackrabbit.test.config.xml; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.Enumeration; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.jackrabbit.test.config.AccessManagerConf; +import org.apache.jackrabbit.test.config.BeanConf; +import org.apache.jackrabbit.test.config.ClusterConf; +import org.apache.jackrabbit.test.config.JournalConf; +import org.apache.jackrabbit.test.config.LoginModuleConf; +import org.apache.jackrabbit.test.config.PersistenceManagerConf; +import org.apache.jackrabbit.test.config.RepositoryConf; +import org.apache.jackrabbit.test.config.SearchConf; +import org.apache.jackrabbit.test.config.SecurityConf; +import org.apache.jackrabbit.test.config.VersioningConf; +import org.apache.jackrabbit.test.config.WorkspaceConf; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * RepositoryConfigurationWriter ... + * + */ +public class RepositoryConfWriter { + + public static void write(RepositoryConf rc, String file) throws ConfException { + write(rc, new File(file)); + } + + public static void write(RepositoryConf rc, File file) throws ConfException { + Writer configWriter = null; + try { + configWriter = new FileWriter(file); + + Element root = createRepositoryConfElement(rc); + + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.transform(new DOMSource(root), new StreamResult(configWriter)); + } catch (Exception e) { + throw new ConfException( + "Failed to create repository configuration at path " + + file.getPath(), e); + } finally { + try { + if (configWriter != null) { + configWriter.close(); + } + } catch (IOException ignore) { + } + } + } + + public static Element createRepositoryConfElement(RepositoryConf rc) throws ConfException { + RepositoryConfWriter writer = new RepositoryConfWriter(); + Element root = writer.writeRepositoryConf(rc); + // make it the root element + writer.document.appendChild(root); + return root; + } + + public static Element createWorkspaceConfElement(WorkspaceConf wc) throws ConfException { + RepositoryConfWriter writer = new RepositoryConfWriter(); + return writer.writeWorkspaceConf(wc); + } + + /** Static factory for creating DOM DocumentBuilder instances. */ + private static final DocumentBuilderFactory BUILDER_FACTORY = DocumentBuilderFactory.newInstance(); + + protected Document document; + + protected RepositoryConfWriter() throws ConfException { + try { + document = BUILDER_FACTORY.newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException e) { + throw new ConfException("Could create SAX parser for RepositoryConfWriter", e); + } + } + + protected Element writeRepositoryConf(RepositoryConf rc) { + Element element = document.createElement("Repository"); + element.appendChild(writeBeanConf(rc.getFileSystemConf(), Xml.FILE_SYSTEM_ELEMENT)); + element.appendChild(writeSecurityConf(rc.getSecurityConf())); + + Element workspaces = document.createElement(Xml.WORKSPACES_ELEMENT); + workspaces.setAttribute(Xml.ROOT_PATH_ATTRIBUTE, rc.getWorkspaceDirectory()); + workspaces.setAttribute(Xml.CONFIG_ROOT_PATH_ATTRIBUTE, rc.getWorkspaceConfigDirectory()); + workspaces.setAttribute(Xml.DEFAULT_WORKSPACE_ATTRIBUTE, rc.getDefaultWorkspaceName()); + element.appendChild(workspaces); + + element.appendChild(writeWorkspaceConf(rc.getWorkspaceConfTemplate())); + + element.appendChild(writeVersioningConf(rc.getVersioningConf())); + element.appendChild(writeSearchConf(rc.getSearchConf())); + + if (rc.getClusterConf() != null) { + element.appendChild(writeClusterConf(rc.getClusterConf())); + } + + return element; + } + + protected Element writeWorkspaceConf(WorkspaceConf wc) { + Element element = document.createElement(Xml.WORKSPACE_ELEMENT); + element.setAttribute(Xml.NAME_ATTRIBUTE, wc.getName()); + element.setAttribute(Xml.CLUSTERED_ATTRIBUTE, wc.isClustered() ? "true" : "false"); + + element.appendChild(writeBeanConf(wc.getFileSystemConf(), Xml.FILE_SYSTEM_ELEMENT)); + element.appendChild(writePersistenceManagerConf(wc.getPersistenceManagerConf())); + element.appendChild(writeSearchConf(wc.getSearchConf())); + return element; + } + + protected Element writeBeanConf(BeanConf bc, String name) { + Element element = document.createElement(name); + element.setAttribute(Xml.CLASS_ATTRIBUTE, bc.getClassName()); + for (Enumeration keys = bc.getParameters().keys(); keys.hasMoreElements();) { + String key = (String) keys.nextElement(); + String value = bc.getParameters().getProperty(key); + + Element child = document.createElement(Xml.PARAM_ELEMENT); + child.setAttribute(Xml.NAME_ATTRIBUTE, key); + child.setAttribute(Xml.VALUE_ATTRIBUTE, value); + element.appendChild(child); + } + return element; + } + + protected Element writeSecurityConf(SecurityConf sc) { + Element element = document.createElement(Xml.SECURITY_ELEMENT); + element.setAttribute(Xml.APP_NAME_ATTRIBUTE, sc.getAppName()); + + element.appendChild(writeAccessManagerConf(sc.getAccessManagerConf())); + + if (sc.getLoginModuleConf() != null) { + element.appendChild(writeLoginModuleConf(sc.getLoginModuleConf())); + } + return element; + } + + protected Element writeAccessManagerConf(AccessManagerConf ac) { + return writeBeanConf(ac, Xml.ACCESS_MANAGER_ELEMENT); + } + + protected Element writeLoginModuleConf(LoginModuleConf lc) { + return writeBeanConf(lc, Xml.LOGIN_MODULE_ELEMENT); + } + + protected Element writeSearchConf(SearchConf sc) { + Element element = writeBeanConf(sc, Xml.SEARCH_INDEX_ELEMENT); + if (sc.getFileSystemConf() != null) { + element.appendChild(writeBeanConf(sc.getFileSystemConf(), Xml.FILE_SYSTEM_ELEMENT)); + } + return element; + } + + protected Element writeVersioningConf(VersioningConf vc) { + Element element = document.createElement(Xml.VERSIONING_ELEMENT); + element.setAttribute(Xml.ROOT_PATH_ATTRIBUTE, vc.getHomeDir()); + + element.appendChild(writeBeanConf(vc.getFileSystemConf(), Xml.FILE_SYSTEM_ELEMENT)); + element.appendChild(writePersistenceManagerConf(vc.getPersistenceManagerConf())); + return element; + } + + protected Element writeClusterConf(ClusterConf cc) { + Element element = document.createElement(Xml.CLUSTER_ELEMENT); + element.setAttribute(Xml.ID_ATTRIBUTE, cc.getId()); + element.setAttribute(Xml.SYNC_DELAY_ATTRIBUTE, Long.toString(cc.getSyncDelay())); + + element.appendChild(writeJournalConf(cc.getJournalConf())); + return element; + } + + protected Element writeJournalConf(JournalConf jc) { + return writeBeanConf(jc, Xml.JOURNAL_ELEMENT); + } + + protected Element writePersistenceManagerConf(PersistenceManagerConf pmc) { + return writeBeanConf(pmc, Xml.PERSISTENCE_MANAGER_ELEMENT); + } + +} Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/Xml.java =================================================================== --- jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/Xml.java (revision 0) +++ jackrabbit-core/src/test/java/org/apache/jackrabbit/test/config/xml/Xml.java (revision 0) @@ -0,0 +1,15 @@ +package org.apache.jackrabbit.test.config.xml; + +import java.util.Properties; + +import org.apache.jackrabbit.core.config.RepositoryConfigurationParser; + +/** + * Helper for shorter access to {@link RepositoryConfigurationParser} constants. + */ +public class Xml extends RepositoryConfigurationParser { + + public Xml(Properties variables) { + super(variables); + } +} \ No newline at end of file