/** * Copyright 2012 Manning Publications Co. * * Licensed 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 com.manning.cmis.theblend.servlets; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.chemistry.opencmis.client.api.CmisObject; import org.apache.chemistry.opencmis.client.api.Document; import org.apache.chemistry.opencmis.client.api.Folder; import org.apache.chemistry.opencmis.client.api.ObjectId; import org.apache.chemistry.opencmis.client.api.Session; import org.apache.chemistry.opencmis.commons.PropertyIds; import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException; import com.manning.cmis.theblend.session.IdMapping; import com.manning.cmis.theblend.util.CMISHelper; import com.manning.cmis.theblend.util.HTMLHelper; import com.manning.cmis.theblend.util.TheBlendHelper; public class AlbumServlet extends AbstractTheBlendServlet { private static final long serialVersionUID = 1L; private static final String PARAM_ID = "id"; private static final String PARAM_ACTION = "action"; private static final String PARAM_PARENT_PATH = "parentpath"; private static final String PARAM_PARENT_ID = "parentid"; private static final String PARAM_NAME = "name"; private static final String PARAM_TRACK_WHAT = "what"; private static final String PARAM_TRACK_ID = "trackid"; private static final String PARAM_TRACK_PATH = "trackpath"; public static final String ATTR_OBJECT = "object"; public static final String ATTR_TRACKS = "tracks"; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response, Session session) throws ServletException, IOException, TheBlendException { String id = getRequiredStringParameter(request, PARAM_ID); // fetch the album object Document album = CMISHelper.getDocumet(session, id, CMISHelper.FULL_OPERATION_CONTEXT, "album"); // check if the object has the cmisbook:tracks property if (!album .getType() .getPropertyDefinitions() .containsKey( IdMapping.getRepositoryPropertyId("cmisbook:tracks"))) { throw new TheBlendException( "Document has no cmisbook:tracks property!"); } request.setAttribute(ATTR_OBJECT, album); // get the tracks List<Document> tracks = TheBlendHelper.getTracks(session, album); request.setAttribute(ATTR_TRACKS, tracks); // show album page dispatch("album.jsp", album.getName() + " .The Blend.", request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response, Session session) throws ServletException, IOException, TheBlendException { // find out what to do int action = getIntParameter(request, PARAM_ACTION, 0); if (action < 1 && action > 3) { throw new TheBlendException("Unknown action!"); } ObjectId newId = null; if (action == 1) { // create new album newId = createAlbum(session, request); } else { // album update, get its id String id = getRequiredStringParameter(request, PARAM_ID); // fetch the album object Document album = CMISHelper.getDocumet(session, id, CMISHelper.FULL_OPERATION_CONTEXT, "album"); // check if the object has the cmisbook:tracks property if (!album .getType() .getPropertyDefinitions() .containsKey( IdMapping.getRepositoryPropertyId("cmisbook:tracks"))) { error("Document has no cmisbook:tracks property!", null, request, response); return; } List<String> tracks = null; if (action == 2) { // update track list tracks = getTrackList(request); } else if (action == 3) { // add track to album List<String> orgTracks = album.getPropertyValue(IdMapping .getRepositoryPropertyId("cmisbook:tracks")); tracks = addTrack(session, request, orgTracks); } // update the track list Map<String, Object> properties = new HashMap<String, Object>(); properties.put( IdMapping.getRepositoryPropertyId("cmisbook:tracks"), tracks); try { CmisObject newObject = album.updateProperties(properties); newId = newObject; } catch (CmisBaseException cbe) { throw new TheBlendException("Could not update track list!", cbe); } } // return to album page redirect( HTMLHelper.encodeUrlWithId(request, "album", newId.getId()), request, response); } protected ObjectId createAlbum(Session session, HttpServletRequest request) throws TheBlendException { String parentId = getStringParameter(request, PARAM_PARENT_ID); String parentPath = getStringParameter(request, PARAM_PARENT_PATH); String name = getStringParameter(request, PARAM_NAME); if (name == null || name.length() == 0) { name = "The Blend"; } // fetch the parent folder Folder parent = null; if (parentId != null) { parent = CMISHelper.getFolder(session, parentId, CMISHelper.LIGHT_OPERATION_CONTEXT, "parent folder"); } else if (parentPath != null) { parent = CMISHelper.getFolderByPath(session, parentPath, CMISHelper.LIGHT_OPERATION_CONTEXT, "parent folder"); } else { parent = CMISHelper.getFolder(session, getApplicationRootFolderId(request), CMISHelper.LIGHT_OPERATION_CONTEXT, "parent folder"); } // create a document without content Map<String, Object> properties = new HashMap<String, Object>(); properties.put(PropertyIds.NAME, name); properties.put(PropertyIds.OBJECT_TYPE_ID, IdMapping.getRepositoryTypeId("cmisbook:album")); return session.createDocument(properties, parent, null, null); } protected List<String> getTrackList(HttpServletRequest request) { List<TrackPosition> trackList = new ArrayList<AlbumServlet.TrackPosition>(); // get the track list int x = 0; String trackId = getStringParameter(request, "id_" + x); while (trackId != null) { if (getIntParameter(request, "remove_" + x, 0) != 1) { int pos = getIntParameter(request, "pos_" + x, 0); trackList.add(new TrackPosition(trackId, pos)); } x++; trackId = getStringParameter(request, "id_" + x); } // sort the track list Collections.sort(trackList, new Comparator<TrackPosition>() { @Override public int compare(TrackPosition t1, TrackPosition t2) { if (t1.getPosition() < t2.getPosition()) { return -1; } else if (t1.getPosition() > t2.getPosition()) { return 1; } else { return 0; } } }); // prepare the track list for update List<String> tracks = new ArrayList<String>(); for (TrackPosition tp : trackList) { tracks.add(tp.getTrackId()); } return tracks; } protected List<String> addTrack(Session session, HttpServletRequest request, List<String> orgsTracks) throws TheBlendException { String what = getRequiredStringParameter(request, PARAM_TRACK_WHAT); Document track = null; if (what.equalsIgnoreCase("id")) { String trackId = getStringParameter(request, PARAM_TRACK_ID); track = CMISHelper.getDocumet(session, trackId, CMISHelper.FULL_OPERATION_CONTEXT, "track"); } else if (what.equalsIgnoreCase("path")) { String trackPath = getStringParameter(request, PARAM_TRACK_PATH); track = CMISHelper.getDocumetByPath(session, trackPath, CMISHelper.FULL_OPERATION_CONTEXT, "track"); } else { throw new TheBlendException("What?"); } // check track MIME type String trackMimeType = track.getContentStreamMimeType(); if (trackMimeType == null) { throw new TheBlendException("Track has no content!"); } if (!trackMimeType.toLowerCase().startsWith("audio/")) { throw new TheBlendException("Track in not an audio file!"); } if (orgsTracks.contains(track.getId())) { // the track is already in the track list return orgsTracks; } else { // add track to track list List<String> tracks = new ArrayList<String>(orgsTracks); tracks.add(track.getId()); return tracks; } } protected static class TrackPosition { final private String trackId; final private int position; public TrackPosition(String trackId, int position) { this.trackId = trackId; this.position = position; } public String getTrackId() { return trackId; } public int getPosition() { return position; } } }