private void processChunk()

in src/main/java/org/apache/sling/servlets/post/impl/helper/SlingFileUploadHandler.java [196:304]


    private void processChunk(
            final Resource resParent,
            final Resource res,
            final RequestProperty prop,
            final RequestParameter value,
            final List<Modification> changes)
            throws PersistenceException {
        try {
            final ModifiableValueMap mvm = res.adaptTo(ModifiableValueMap.class);
            long chunkOffset = prop.getChunk().getOffset();
            if (chunkOffset == 0) {
                // first chunk
                // check if another chunk upload is already in progress. throw
                // exception
                final Iterator<Resource> itr =
                        new FilteringResourceIterator(res.listChildren(), SlingPostConstants.CHUNK_NODE_NAME);
                if (itr.hasNext()) {
                    throw new PersistenceException("Chunk upload already in progress at {" + res.getPath() + "}");
                }
                addChunkMixin(mvm);
                mvm.put(SlingPostConstants.NT_SLING_CHUNKS_LENGTH, 0);
                changes.add(Modification.onModified(res.getPath() + "/" + SlingPostConstants.NT_SLING_CHUNKS_LENGTH));
                if (mvm.get(JcrConstants.JCR_DATA) == null) {
                    // create a empty jcr:data property
                    mvm.put(JcrConstants.JCR_DATA, new ByteArrayInputStream("".getBytes()));
                }
            }
            if (mvm.get(SlingPostConstants.NT_SLING_CHUNKS_LENGTH) == null) {
                throw new PersistenceException("no chunk upload found at {" + res.getPath() + "}");
            }
            long currentLength = mvm.get(SlingPostConstants.NT_SLING_CHUNKS_LENGTH, Long.class);
            long totalLength = prop.getChunk().getLength();
            if (chunkOffset != currentLength) {
                throw new PersistenceException(
                        "Chunk's offset {" + chunkOffset + "} doesn't match expected offset {" + currentLength + "}");
            }
            if (totalLength != 0) {
                if (mvm.get(SlingPostConstants.NT_SLING_FILE_LENGTH) != null) {
                    long expectedLength = mvm.get(SlingPostConstants.NT_SLING_FILE_LENGTH, Long.class);
                    if (totalLength != expectedLength) {
                        throw new PersistenceException("File length {"
                                + totalLength + "} doesn't match expected length {"
                                + expectedLength + "}");
                    }
                } else {
                    mvm.put(SlingPostConstants.NT_SLING_FILE_LENGTH, totalLength);
                }
            }
            final Iterator<Resource> itr = new FilteringResourceIterator(
                    res.listChildren(), SlingPostConstants.CHUNK_NODE_NAME + "_" + String.valueOf(chunkOffset));
            if (itr.hasNext()) {
                throw new PersistenceException(
                        "Chunk already present at {" + itr.next().getPath() + "}");
            }
            String nodeName = SlingPostConstants.CHUNK_NODE_NAME + "_"
                    + String.valueOf(chunkOffset) + "_"
                    + String.valueOf(chunkOffset + value.getSize() - 1);
            if (totalLength == (currentLength + value.getSize())
                    || prop.getChunk().isCompleted()) {
                File file = null;
                InputStream fileIns = null;
                try {
                    file = mergeChunks(res, value.getInputStream());
                    fileIns = new FileInputStream(file);
                    mvm.put(JcrConstants.JCR_DATA, fileIns);
                    changes.add(Modification.onModified(res.getPath() + "/" + JcrConstants.JCR_DATA));
                    final Iterator<Resource> rsrcItr =
                            new FilteringResourceIterator(res.listChildren(), SlingPostConstants.CHUNK_NODE_NAME);
                    while (rsrcItr.hasNext()) {
                        Resource rsrcRange = rsrcItr.next();
                        changes.add(Modification.onDeleted(rsrcRange.getPath()));
                        rsrcRange.getResourceResolver().delete(rsrcRange);
                    }
                    if (mvm.get(SlingPostConstants.NT_SLING_FILE_LENGTH) != null) {
                        changes.add(
                                Modification.onDeleted(res.getPath() + "/" + SlingPostConstants.NT_SLING_FILE_LENGTH));
                        mvm.remove(SlingPostConstants.NT_SLING_FILE_LENGTH);
                    }
                    if (mvm.get(SlingPostConstants.NT_SLING_CHUNKS_LENGTH) != null) {
                        changes.add(Modification.onDeleted(
                                res.getPath() + "/" + SlingPostConstants.NT_SLING_CHUNKS_LENGTH));
                        mvm.remove(SlingPostConstants.NT_SLING_CHUNKS_LENGTH);
                    }
                    removeChunkMixin(mvm);
                } finally {
                    try {
                        fileIns.close();
                        file.delete();
                    } catch (IOException ign) {

                    }
                }
            } else {
                final Map<String, Object> props = new HashMap<>();
                props.put(JcrConstants.JCR_DATA, value.getInputStream());
                props.put(SlingPostConstants.NT_SLING_CHUNK_OFFSET, chunkOffset);
                props.put(SlingPostConstants.NT_SLING_CHUNKS_LENGTH, currentLength + value.getSize());
                for (final String key : props.keySet()) {
                    changes.add(Modification.onModified(res.getPath() + "/" + nodeName + "/" + key));
                }
                props.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, SlingPostConstants.NT_SLING_CHUNK_NODETYPE);
                final Resource rangeRsrc = res.getResourceResolver().create(res, nodeName, props);

                changes.add(Modification.onCreated(rangeRsrc.getPath()));
            }
        } catch (IOException e) {
            throw new PersistenceException("Error while retrieving inputstream from parameter value.", e);
        }
    }