core/src/main/java/org/sakaiproject/nakamura/lite/content/ContentManagerImpl.java
public void copy(String from, String to, boolean withStreams) throws StorageClientException, AccessDeniedException, IOException {
        long ts = System.currentTimeMillis();
        try {
            checkOpen();
            // To Copy, get the to object out and copy everything over.
            Content f = get(from);
            if (f == null) {
                throw new StorageClientException(" Source content " + from + " does not exist");
            }
            if (f.getProperty(UUID_FIELD) == null) {
                LOGGER.warn("Bad Content item with no ID cant be copied {} ", f);
                throw new StorageClientException(" Source content " + from + "  Has no " + UUID_FIELD);
            }
            Content t = get(to);
            if (t != null) {
                LOGGER.debug("Deleting {} ", to);
                delete(to);
            }
            Set<String> streams = Sets.newHashSet();
            Map<String, Object> copyProperties = Maps.newHashMap();
            if (withStreams) {
                for (Entry<String, Object> p : f.getProperties().entrySet()) {
                    // Protected fields (such as ID and path) will differ
                    // between
                    // the source and destination, so don't copy them.
                    if (!PROTECTED_FIELDS.contains(p.getKey())) {
                        if (p.getKey().startsWith(BLOCKID_FIELD)) {
                            streams.add(p.getKey());
                        } else {
                            copyProperties.put(p.getKey(), p.getValue());
                        }
                    }
                }
            } else {
                copyProperties.putAll(f.getProperties());
            }
            copyProperties.put(COPIED_FROM_PATH_FIELD, from);
            copyProperties.put(COPIED_FROM_ID_FIELD, f.getProperty(UUID_FIELD));
            copyProperties.put(COPIED_DEEP_FIELD, withStreams);
            t = new Content(to, copyProperties);
            update(t);
            LOGGER.debug("Copy Updated {} {} ", to, t);

            for (String stream : streams) {
                String streamId = null;
                if (stream.length() > BLOCKID_FIELD.length()) {
                    streamId = stream.substring(BLOCKID_FIELD.length() + 1);
                }
                InputStream fromStream = getInputStream(from, streamId);
                writeBody(to, fromStream);
                fromStream.close();
            }
            eventListener.onUpdate(Security.ZONE_CONTENT, to, accessControlManager.getCurrentUserId(), getResourceType(f), true,
                    null, "op:copy");
        } finally {
            statsService.apiCall(ContentManagerImpl.class.getName(), "copy", System.currentTimeMillis() - ts);
        }

    }
public void copy(String from, String to, boolean withStreams) throws StorageClientException, AccessDeniedException, IOException {
        long ts = System.currentTimeMillis();
        try {
            checkOpen();
            // To Copy, get the to object out and copy everything over.
            Content f = get(from);
            if (f == null) {
                throw new StorageClientException(" Source content " + from + " does not exist");
            }
            if (f.getProperty(UUID_FIELD) == null) {
                LOGGER.warn("Bad Content item with no ID cant be copied {} ", f);
                throw new StorageClientException(" Source content " + from + "  Has no " + UUID_FIELD);
            }
            Content t = get(to);
            if (t != null) {
                LOGGER.debug("Deleting {} ", to);
                delete(to);
            }
            Set<String> streams = Sets.newHashSet();
            Map<String, Object> copyProperties = Maps.newHashMap();
            if (withStreams) {
                for (Entry<String, Object> p : f.getProperties().entrySet()) {
                    // Protected fields (such as ID and path) will differ
                    // between
                    // the source and destination, so don't copy them.
                    if (!PROTECTED_FIELDS.contains(p.getKey())) {
                        if (p.getKey().startsWith(BLOCKID_FIELD)) {
                            streams.add(p.getKey());
                        } else {
                            copyProperties.put(p.getKey(), p.getValue());
                        }
                    }
                }
            } else {
                copyProperties.putAll(f.getProperties());
            }
            copyProperties.put(COPIED_FROM_PATH_FIELD, from);
            copyProperties.put(COPIED_FROM_ID_FIELD, f.getProperty(UUID_FIELD));
            copyProperties.put(COPIED_DEEP_FIELD, withStreams);
            t = new Content(to, copyProperties);
            update(t);
            LOGGER.debug("Copy Updated {} {} ", to, t);

            for (String stream : streams) {
                String streamId = null;
                if (stream.length() > BLOCKID_FIELD.length()) {
                    streamId = stream.substring(BLOCKID_FIELD.length() + 1);
                }
                InputStream fromStream = getInputStream(from, streamId);
                writeBody(to, fromStream);
                fromStream.close();
            }
            eventListener.onUpdate(Security.ZONE_CONTENT, to, accessControlManager.getCurrentUserId(), getResourceType(f), true,
                    null, "op:copy");
        } finally {
            statsService.apiCall(ContentManagerImpl.class.getName(), "copy", System.currentTimeMillis() - ts);
        }

    }
{@inheritDoc}

@see org.sakaiproject.nakamura.api.lite.content.ContentManager#copy(java.lang.String,
java.lang.String, boolean)