private void persistBinaryContent(JcrRepository repository) throws RepositoryException, IOException { assertNotNull(repository); long minimumBinarySize = repository.getConfiguration().getBinaryStorage().getMinimumBinarySizeInBytes(); long binarySize = minimumBinarySize + 1; Session session = repository.login(); InputStream binaryValueStream = null; try { byte[] content = new byte[(int) binarySize]; new Random().nextBytes(content); JCR_TOOLS.uploadFile(session, "folder/file", new ByteArrayInputStream(content)); session.save(); Node nodeWithBinaryContent = session.getNode("/folder/file/jcr:content"); Binary binaryValue = nodeWithBinaryContent.getProperty("jcr:data").getBinary(); binaryValueStream = binaryValue.getStream(); byte[] retrievedContent = IoUtil.readBytes(binaryValueStream); assertArrayEquals(content, retrievedContent); } finally { if (binaryValueStream != null) { binaryValueStream.close(); } session.logout(); } }
@Override public NodeTypeIterator registerNodeTypes(URL url, boolean allowUpdate) throws IOException, RepositoryException { String content = IoUtil.read(url.openStream()); if (content.startsWith("<?xml")) { // This is Jackrabbit XML format ... return registerNodeTypes( importFromXml(new InputSource(new StringReader(content))), allowUpdate); } // Assume this is CND format ... CndImporter importer = new CndImporter(context(), true); Problems problems = new SimpleProblems(); importer.importFrom(content, problems, url.toExternalForm()); // Check for (and report) any problems ... if (problems.hasProblems()) { // There are errors and/or warnings, so report them ... String summary = messageFrom(problems); if (problems.hasErrors()) { String msg = JcrI18n.errorsParsingNodeTypeDefinitions.text(url.toExternalForm(), summary); throw new RepositoryException(msg); } // Otherwise, there are warnings, so log them ... I18n msg = JcrI18n.warningsParsingNodeTypeDefinitions; Logger.getLogger(getClass()).warn(msg, url.toExternalForm(), summary); } // Register the node types ... return registerNodeTypes(importer.getNodeTypeDefinitions(), allowUpdate); }
protected Binary storeAndCheck(int contentIndex, Class<? extends Binary> valueClass) throws Exception { String content = CONTENT[contentIndex]; String sha1 = CONTENT_HASHES[contentIndex]; InputStream stream = new ByteArrayInputStream(content.getBytes()); Stopwatch sw = new Stopwatch(); sw.start(); Binary binary = store.storeValue(stream, false); sw.stop(); if (print) System.out.println("Time to store 18MB file: " + sw.getTotalDuration()); if (valueClass != null) { assertThat(binary, is(instanceOf(valueClass))); } if (content.length() == 0) { assertThat(binary, is(instanceOf(EmptyBinaryValue.class))); } else if (content.length() < MIN_BINARY_SIZE) { assertThat(binary, is(instanceOf(InMemoryBinaryValue.class))); } else { assertThat(binary, is(instanceOf(StoredBinaryValue.class))); } assertThat(binary.getHexHash(), is(sha1)); String binaryContent = IoUtil.read(binary.getStream()); assertThat(binaryContent, is(content)); return binary; }
@FixFor("MODE-1358") @Test public void shouldCopyFilesUsingStreams() throws Exception { // Copy a large file into a temporary file ... File tempFile = File.createTempFile("copytest", "pdf"); RandomAccessFile destinationRaf = null; RandomAccessFile originalRaf = null; try { URL sourceUrl = getClass().getResource("/docs/postgresql-8.4.1-US.pdf"); assertThat(sourceUrl, is(notNullValue())); File sourceFile = new File(sourceUrl.toURI()); assertThat(sourceFile.exists(), is(true)); assertThat(sourceFile.canRead(), is(true)); assertThat(sourceFile.isFile(), is(true)); boolean useBufferedStream = true; final int bufferSize = AbstractBinaryStore.bestBufferSize(sourceFile.length()); destinationRaf = new RandomAccessFile(tempFile, "rw"); originalRaf = new RandomAccessFile(sourceFile, "r"); FileChannel destinationChannel = destinationRaf.getChannel(); OutputStream output = Channels.newOutputStream(destinationChannel); if (useBufferedStream) output = new BufferedOutputStream(output, bufferSize); // Create an input stream to the original file ... FileChannel originalChannel = originalRaf.getChannel(); InputStream input = Channels.newInputStream(originalChannel); if (useBufferedStream) input = new BufferedInputStream(input, bufferSize); // Copy the content ... Stopwatch sw = new Stopwatch(); sw.start(); IoUtil.write(input, output, bufferSize); sw.stop(); System.out.println( "Time to copy \"" + sourceFile.getName() + "\" (" + sourceFile.length() + " bytes): " + sw.getTotalDuration()); } finally { tempFile.delete(); if (destinationRaf != null) destinationRaf.close(); if (originalRaf != null) originalRaf.close(); } }
protected Map<Name, Property> load(File propertiesFile, ExecutionContext context) throws RepositorySourceException { if (!propertiesFile.exists() || !propertiesFile.canRead()) return NO_PROPERTIES_MAP; try { String content = IoUtil.read(propertiesFile); ValueFactories factories = context.getValueFactories(); PropertyFactory propFactory = context.getPropertyFactory(); Map<Name, Property> result = new HashMap<Name, Property>(); for (String line : StringUtil.splitLines(content)) { // Parse each line ... Property property = parse(line, factories, propFactory); if (property != null) { result.put(property.getName(), property); } } return result; } catch (IOException e) { throw new RepositorySourceException(sourceName, e); } }
@Test public void shouldCleanTrashFilesWhenFilesBecomeUsed() throws Exception { Set<Binary> binaries = new HashSet<Binary>(); int storedCount = 0; for (int i = 0; i != CONTENT.length; ++i) { Binary binary = storeAndCheck(i); assertThat(binary, is(notNullValue())); binaries.add(binary); if (binary instanceof StoredBinaryValue) storedCount++; } // Make sure there are files for all stored values ... assertThat(countStoredFiles(), is(storedCount)); assertThat(countTrashFiles(), is(0)); // Mark one of the files as being unused ... String unused = binaries.iterator().next().getHexHash(); BinaryKey unusedKey = new BinaryKey(unused); store.markAsUnused(Collections.singleton(unusedKey)); // Make sure the file was moved to the trash ... assertThat(countStoredFiles(), is(storedCount)); assertThat(countTrashFiles(), is(1)); // Now access all the binary files which will not change there used/unused state for (Binary binary : binaries) { InputStream stream = binary.getStream(); String content = IoUtil.read(stream); assertThat(content.length() != 0, is(true)); } // Make sure there are files for all stored values ... assertThat(countStoredFiles(), is(storedCount)); assertThat(countTrashFiles(), is(1)); // Now mark the file explicitly as used and check that the file from the trash was removed store.markAsUsed(Collections.singleton(unusedKey)); assertThat(countTrashFiles(), is(0)); }
protected JcrRepository doCreateJcrRepository(String repositoryName) throws RepositoryException, PathNotFoundException { RepositoryConnectionFactory connectionFactory = getRepositoryConnectionFactory(); Map<String, String> descriptors = new HashMap<String, String>(); Map<Option, String> options = new HashMap<Option, String>(); // Read the subgraph that represents the repository ... PathFactory pathFactory = getExecutionContext().getValueFactories().getPathFactory(); Path repositoriesPath = pathFactory.create(configuration.getPath(), ModeShapeLexicon.REPOSITORIES); Path repositoryPath = pathFactory.create(repositoriesPath, repositoryName); Name repoName = getExecutionContext().getValueFactories().getNameFactory().create(repositoryName); Graph configuration = null; Subgraph subgraph = getConfigurationSubgraph(false); // Read the options ... Path optionsPath = pathFactory.createRelativePath( ModeShapeLexicon.REPOSITORIES, repoName, ModeShapeLexicon.OPTIONS); Node optionsNode = subgraph.getNode(optionsPath); if (optionsNode != null) { for (Location optionLocation : optionsNode.getChildren()) { Node optionNode = subgraph.getNode(optionLocation); Path.Segment segment = optionLocation.getPath().getLastSegment(); Property valueProperty = optionNode.getProperty(ModeShapeLexicon.VALUE); if (valueProperty == null) { log.warn(JcrI18n.noOptionValueProvided, segment.getName().getLocalName()); continue; } Option option = Option.findOption(segment.getName().getLocalName()); if (option == null) { log.warn(JcrI18n.invalidOptionProvided, segment.getName().getLocalName()); continue; } options.put(option, valueProperty.getFirstValue().toString()); } } // Disable the derived content removal option if not explicitly set and no sequencers ... if (!options.containsKey(Option.REMOVE_DERIVED_CONTENT_WITH_ORIGINAL) && getSequencingService().getSequencers().isEmpty()) { options.put(Option.REMOVE_DERIVED_CONTENT_WITH_ORIGINAL, Boolean.FALSE.toString()); } // Read the descriptors ... Path descriptorsPath = pathFactory.createRelativePath( ModeShapeLexicon.REPOSITORIES, repoName, ModeShapeLexicon.DESCRIPTORS); Node descriptorsNode = subgraph.getNode(descriptorsPath); if (descriptorsNode != null) { for (Location descriptorLocation : descriptorsNode.getChildren()) { Node optionNode = subgraph.getNode(descriptorLocation); Path.Segment segment = descriptorLocation.getPath().getLastSegment(); Property valueProperty = optionNode.getProperty(ModeShapeLexicon.VALUE); if (valueProperty == null) continue; descriptors.put(segment.getName().getLocalName(), valueProperty.getFirstValue().toString()); } } // Read the namespaces ... ExecutionContext context = getExecutionContext(); Path namespacesPath = pathFactory.createRelativePath( ModeShapeLexicon.REPOSITORIES, repoName, ModeShapeLexicon.NAMESPACES); Node namespacesNode = subgraph.getNode(namespacesPath); descriptors.put(org.modeshape.jcr.api.Repository.REPOSITORY_NAME, repositoryName); if (namespacesNode != null) { configuration = getConfigurationGraph(); GraphNamespaceRegistry registry = new GraphNamespaceRegistry( configuration, namespacesNode.getLocation().getPath(), ModeShapeLexicon.URI, ModeShapeLexicon.GENERATED); context = context.with(registry); } // Get the name of the source ... Path repoPath = pathFactory.createRelativePath(ModeShapeLexicon.REPOSITORIES, repoName); Node repoNode = subgraph.getNode(repoPath); if (repoNode == null) { // There is no repository with the supplied name ... throw new PathNotFoundException( Location.create(repoPath), repositoriesPath, JcrI18n.repositoryDoesNotExist.text(readable(repoName))); } Property property = repoNode.getProperty(ModeShapeLexicon.SOURCE_NAME); if (property == null || property.isEmpty()) { if (configuration == null) configuration = getConfigurationGraph(); String readableName = readable(ModeShapeLexicon.SOURCE_NAME); String readablePath = readable(subgraph.getLocation()); String msg = JcrI18n.propertyNotFoundOnNode.text( readableName, readablePath, configuration.getCurrentWorkspaceName()); throw new RepositoryException(msg); } String sourceName = context.getValueFactories().getStringFactory().create(property.getFirstValue()); // Verify the sourc exists ... RepositorySource source = getRepositorySource(sourceName); if (source == null) { throw new RepositoryException( JcrI18n.repositoryReferencesNonExistantSource.text(repositoryName, sourceName)); } // Read the initial content ... String initialContentForNewWorkspaces = null; for (Location initialContentLocation : repoNode.getChildren(ModeShapeLexicon.INITIAL_CONTENT)) { Node initialContent = subgraph.getNode(initialContentLocation); if (initialContent == null) continue; // Determine where to load the initial content from ... Property contentReference = initialContent.getProperty(ModeShapeLexicon.CONTENT); if (contentReference == null || contentReference.isEmpty()) { if (configuration == null) configuration = getConfigurationGraph(); String readableName = readable(ModeShapeLexicon.CONTENT); String readablePath = readable(initialContentLocation); String msg = JcrI18n.propertyNotFoundOnNode.text( readableName, readablePath, configuration.getCurrentWorkspaceName()); throw new RepositoryException(msg); } String contentRef = string(contentReference.getFirstValue()); // Determine which workspaces this should apply to ... Property workspaces = initialContent.getProperty(ModeShapeLexicon.WORKSPACES); if (workspaces == null || workspaces.isEmpty()) { if (configuration == null) configuration = getConfigurationGraph(); String readableName = readable(ModeShapeLexicon.WORKSPACES); String readablePath = readable(initialContentLocation); String msg = JcrI18n.propertyNotFoundOnNode.text( readableName, readablePath, configuration.getCurrentWorkspaceName()); throw new RepositoryException(msg); } // Load the initial content into a transient source ... XmlFileRepositorySource initialContentSource = new XmlFileRepositorySource(); initialContentSource.setName("Initial content for " + repositoryName); initialContentSource.setContentLocation(contentRef); Graph initialContentGraph = Graph.create(initialContentSource, context); Graph sourceGraph = Graph.create(sourceName, connectionFactory, context); // And initialize the source with the content (if not already there) ... for (Object value : workspaces) { String workspaceName = string(value); if (workspaceName != null && workspaceName.trim().length() != 0) { // Load the content into the workspace with this name ... sourceGraph.useWorkspace(workspaceName); try { sourceGraph.merge(initialContentGraph); } catch (RuntimeException e) { throw new RepositoryException( JcrI18n.unableToImportInitialContent.text(readable(repoName), contentRef), e); } } } // Determine if this initial content should apply to new workspaces ... Property applyToNewWorkspaces = initialContent.getProperty(ModeShapeLexicon.APPLY_TO_NEW_WORKSPACES); if (applyToNewWorkspaces != null && !applyToNewWorkspaces.isEmpty() && isTrue(applyToNewWorkspaces.getFirstValue())) { initialContentForNewWorkspaces = contentRef; // may overwrite the value if seen more than once! } } // Find the capabilities ... RepositorySourceCapabilities capabilities = source.getCapabilities(); // Create the repository ... JcrRepository repository = new JcrRepository( context, connectionFactory, sourceName, getRepositoryService().getRepositoryLibrary(), capabilities, descriptors, options, initialContentForNewWorkspaces); // Register all the the node types ... Path nodeTypesPath = pathFactory.createRelativePath( ModeShapeLexicon.REPOSITORIES, repoName, JcrLexicon.NODE_TYPES); Node nodeTypesNode = subgraph.getNode(nodeTypesPath); if (nodeTypesNode != null) { boolean needToRefreshSubgraph = false; if (configuration == null) configuration = getConfigurationGraph(); // Expand any references to a CND file Property resourceProperty = nodeTypesNode.getProperty(ModeShapeLexicon.RESOURCE); if (resourceProperty != null) { ClassLoader classLoader = this.context.getClassLoader(); for (Object resourceValue : resourceProperty) { String resources = this.context.getValueFactories().getStringFactory().create(resourceValue); for (String resource : resources.split("\\s*,\\s*")) { Graph.Batch batch = configuration.batch(); GraphBatchDestination destination = new GraphBatchDestination(batch); Path nodeTypesAbsPath = pathFactory.create(repositoryPath, JcrLexicon.NODE_TYPES); CndImporter importer = new CndImporter(destination, nodeTypesAbsPath, true, false); InputStream is = IoUtil.getResourceAsStream(resource, classLoader, getClass()); Problems cndProblems = new SimpleProblems(); if (is == null) { String msg = JcrI18n.unableToFindNodeTypeDefinitionsOnClasspathOrFileOrUrl.text(resource); throw new RepositoryException(msg); } try { importer.importFrom(is, cndProblems, resource); batch.execute(); needToRefreshSubgraph = true; } catch (IOException ioe) { String msg = JcrI18n.errorLoadingNodeTypeDefintions.text(resource, ioe.getMessage()); throw new RepositoryException(msg, ioe); } if (!cndProblems.isEmpty()) { // Add any warnings or information to this engine's list ... getProblems().addAll(cndProblems); if (cndProblems.hasErrors()) { String msg = null; Throwable cause = null; for (Problem problem : cndProblems) { if (problem.getStatus() == Status.ERROR) { msg = problem.getMessageString(); cause = problem.getThrowable(); break; } } throw new RepositoryException( JcrI18n.errorLoadingNodeTypeDefintions.text(resource, msg), cause); } } } } } // Load any namespaces from the configuration into the repository's context ... NamespaceRegistry repoRegistry = repository.getExecutionContext().getNamespaceRegistry(); repoRegistry.register(configuration.getContext().getNamespaceRegistry().getNamespaces()); // Re-read the subgraph, in case any new nodes were added Subgraph nodeTypesSubgraph = subgraph; if (needToRefreshSubgraph) { nodeTypesSubgraph = configuration.getSubgraphOfDepth(4).at(nodeTypesNode.getLocation().getPath()); } repository .getRepositoryTypeManager() .registerNodeTypes(nodeTypesSubgraph, nodeTypesNode.getLocation(), false); } return repository; }