From 65ad61b0d8c8dcf3e5ed24aed8f2a4423077432c Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 01:33:13 +0200 Subject: [PATCH 01/16] Add method to process properties from a request. --- .../demoscenemusic/page/admin/AdminBasePage.java | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AdminBasePage.java b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AdminBasePage.java index 040e641..2f4d526 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AdminBasePage.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AdminBasePage.java @@ -17,9 +17,15 @@ package net.pterodactylus.demoscenemusic.page.admin; +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + import net.pterodactylus.demoscenemusic.core.Core; +import net.pterodactylus.demoscenemusic.data.Base; import net.pterodactylus.demoscenemusic.data.User; import net.pterodactylus.demoscenemusic.page.BasePage; +import net.pterodactylus.demoscenemusic.page.ServletRequest; import net.pterodactylus.util.template.Template; import net.pterodactylus.util.template.TemplateContextFactory; @@ -47,6 +53,48 @@ public class AdminBasePage extends BasePage { } // + // PROTECTED METHODS + // + + /** + * Processes properties from the given requests and adjusts the properties + * of the given object. + * + * @param request + * The request to process + * @param object + * The object whose properties to modify + */ + protected void processProperties(ServletRequest request, Base object) { + /* check if properties were changed. */ + List propertiesToDelete = new ArrayList(); + for (Entry property : object.getProperties()) { + if (request.getServletRequest().getParameter("delete." + property.getKey()) != null) { + propertiesToDelete.add(property.getKey()); + continue; + } + String value = request.getServletRequest().getParameter("value." + property.getKey()).trim(); + object.getProperties().set(property.getKey(), value); + } + + /* check if properties are deleted. */ + if (!propertiesToDelete.isEmpty()) { + for (String propertyToDelete : propertiesToDelete) { + object.getProperties().remove(propertyToDelete); + } + } + + /* check for a new property. */ + if ("true".equals(request.getServletRequest().getParameter("new-property"))) { + String property = request.getServletRequest().getParameter("property").trim(); + String value = request.getServletRequest().getParameter("value").trim(); + if ((property.length() > 0) && (value.length() > 0)) { + object.getProperties().set(property, value); + } + } + } + + // // BASEPAGE METHODS // -- 2.7.4 From 82186635a3d6111935a4768b21300ebf0b7465d4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 01:33:23 +0200 Subject: [PATCH 02/16] Use new method in base class. --- .../demoscenemusic/page/admin/EditArtistPage.java | 32 ++-------------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditArtistPage.java b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditArtistPage.java index 09ba5be..8c141fa 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditArtistPage.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditArtistPage.java @@ -17,10 +17,6 @@ package net.pterodactylus.demoscenemusic.page.admin; -import java.util.ArrayList; -import java.util.List; -import java.util.Map.Entry; - import net.pterodactylus.demoscenemusic.core.Core; import net.pterodactylus.demoscenemusic.data.Artist; import net.pterodactylus.demoscenemusic.page.ServletRequest; @@ -73,32 +69,8 @@ public class EditArtistPage extends AdminBasePage { String name = request.getServletRequest().getParameter("name"); artist.setName(name); - /* check if properties were changed. */ - List propertiesToDelete = new ArrayList(); - for (Entry property : artist.getProperties()) { - if (request.getServletRequest().getParameter("delete." + property.getKey()) != null) { - propertiesToDelete.add(property.getKey()); - continue; - } - String value = request.getServletRequest().getParameter("value." + property.getKey()).trim(); - artist.getProperties().set(property.getKey(), value); - } - - /* check if properties are deleted. */ - if (!propertiesToDelete.isEmpty()) { - for (String propertyToDelete : propertiesToDelete) { - artist.getProperties().remove(propertyToDelete); - } - } - - /* check for a new property. */ - if ("true".equals(request.getServletRequest().getParameter("new-property"))) { - String property = request.getServletRequest().getParameter("property").trim(); - String value = request.getServletRequest().getParameter("value").trim(); - if ((property.length() > 0) && (value.length() > 0)) { - artist.getProperties().set(property, value); - } - } + /* process property changes. */ + processProperties(request, artist); getCore().getDataManager().saveArtist(artist); throw new RedirectException("admin.edit-artist?id=" + artist.getId()); -- 2.7.4 From b43317266c8762334078bba06f8aeb2286f8e92c Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 01:35:37 +0200 Subject: [PATCH 03/16] Add page that edits a track. --- .../demoscenemusic/page/admin/EditTrackPage.java | 86 +++++++++++++++++++++ src/main/resources/templates/admin.edit-track | 87 ++++++++++++++++++++++ src/main/webapp/WEB-INF/web.xml.template | 4 + 3 files changed, 177 insertions(+) create mode 100644 src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditTrackPage.java create mode 100644 src/main/resources/templates/admin.edit-track diff --git a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditTrackPage.java b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditTrackPage.java new file mode 100644 index 0000000..def00fb --- /dev/null +++ b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditTrackPage.java @@ -0,0 +1,86 @@ +/* + * DemosceneMusic - EditTrackPage.java - Copyright © 2012 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.demoscenemusic.page.admin; + +import net.pterodactylus.demoscenemusic.core.Core; +import net.pterodactylus.demoscenemusic.data.Track; +import net.pterodactylus.demoscenemusic.page.ServletRequest; +import net.pterodactylus.util.database.DatabaseException; +import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; +import net.pterodactylus.util.template.TemplateContextFactory; +import net.pterodactylus.util.web.Method; +import net.pterodactylus.util.web.RedirectException; + +/** + * Page that lets the user edit a track. + * + * @author David ‘Bombe’ Roden + */ +public class EditTrackPage extends AdminBasePage { + + /** + * Creates a new edit-track page. + * + * @param core + * The core + * @param templateContextFactory + * The template contex factory + * @param template + * The template to render + */ + public EditTrackPage(Core core, TemplateContextFactory templateContextFactory, Template template) { + super(core, templateContextFactory, template, "admin.edit-track"); + } + + // + // BASEPAGE METHODS + // + + /** + * {@inheritDoc} + */ + @Override + protected void processTemplate(TemplateContext templateContext, ServletRequest request) throws RedirectException { + super.processTemplate(templateContext, request); + String trackId = request.getServletRequest().getParameter("id"); + try { + Track track = getCore().getDataManager().getTrackById(trackId); + if (track == null) { + templateContext.set("error", "no-track-given"); + return; + } + + templateContext.set("track", track); + if (request.getMethod() == Method.POST) { + String name = request.getServletRequest().getParameter("name").trim(); + if (name.length() > 0) { + track.setName(name); + } + + /* process properties. */ + processProperties(request, track); + + getCore().getDataManager().saveTrack(track); + } + } catch (DatabaseException de1) { + throw new RuntimeException("Could not edit track.", de1); + } + } + +} diff --git a/src/main/resources/templates/admin.edit-track b/src/main/resources/templates/admin.edit-track new file mode 100644 index 0000000..2cbc3a9 --- /dev/null +++ b/src/main/resources/templates/admin.edit-track @@ -0,0 +1,87 @@ +<%include include/header title=="Edit Track"> + +

Edit Track

+ +
+ + + +
+ Name: + +
+ + + <%foreach track.properties property> + +
+ Property: <%property.key|html> + + Delete +
+ + <%/foreach> + + + +
+ New Property: + + +
+ + +
+ +

Derivatives

+ +<%foreach track.derivatives derivative> + +
+ + + + +
+ Path: + <%derivative.path|html> +
+
+ Size: + <%derivative.size|html> +
+ + <%foreach derivative.properties property> +
+ Property: <%property.key|html> + + Delete +
+ <%/foreach> + +
+ New Property: + + +
+ + +
+ +<%foreachelse> +

This track does not yet have any derivatives.

+<%/foreach> + +

Add a New Derivative

+ +
+ + + + + + + +
+ +<%include include/footer> \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml.template b/src/main/webapp/WEB-INF/web.xml.template index 7f6cde7..48dda54 100644 --- a/src/main/webapp/WEB-INF/web.xml.template +++ b/src/main/webapp/WEB-INF/web.xml.template @@ -78,6 +78,10 @@ admin.edit-artist net.pterodactylus.demoscenemusic.page.admin.EditArtistPage + + admin.edit-track + net.pterodactylus.demoscenemusic.page.admin.EditTrackPage + 0 -- 2.7.4 From 2e353c5053ac5b251c021e6326e291686606bf48 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 01:37:10 +0200 Subject: [PATCH 04/16] Add accessor for track derivatives. --- .../demoscenemusic/core/TemplateServlet.java | 3 ++ .../template/TrackDerivativeAccessor.java | 47 ++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/main/java/net/pterodactylus/demoscenemusic/template/TrackDerivativeAccessor.java diff --git a/src/main/java/net/pterodactylus/demoscenemusic/core/TemplateServlet.java b/src/main/java/net/pterodactylus/demoscenemusic/core/TemplateServlet.java index c1090f2..df753f1 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/core/TemplateServlet.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/core/TemplateServlet.java @@ -41,9 +41,11 @@ import net.pterodactylus.demoscenemusic.data.Artist; import net.pterodactylus.demoscenemusic.data.Properties; import net.pterodactylus.demoscenemusic.data.Style; import net.pterodactylus.demoscenemusic.data.Track; +import net.pterodactylus.demoscenemusic.data.TrackDerivative; import net.pterodactylus.demoscenemusic.data.User; import net.pterodactylus.demoscenemusic.page.ServletRequest; import net.pterodactylus.demoscenemusic.template.PropertiesAccessor; +import net.pterodactylus.demoscenemusic.template.TrackDerivativeAccessor; import net.pterodactylus.demoscenemusic.template.UserAccessor; import net.pterodactylus.util.io.Closer; import net.pterodactylus.util.io.StreamCopier; @@ -85,6 +87,7 @@ public class TemplateServlet extends HttpServlet { templateContextFactory.addAccessor(Object.class, new ReflectionAccessor()); templateContextFactory.addAccessor(User.class, new UserAccessor()); templateContextFactory.addAccessor(Properties.class, new PropertiesAccessor()); + templateContextFactory.addAccessor(TrackDerivative.class, new TrackDerivativeAccessor()); templateContextFactory.addFilter("html", new HtmlFilter()); CollectionSortFilter sortFilter = new CollectionSortFilter(); diff --git a/src/main/java/net/pterodactylus/demoscenemusic/template/TrackDerivativeAccessor.java b/src/main/java/net/pterodactylus/demoscenemusic/template/TrackDerivativeAccessor.java new file mode 100644 index 0000000..66424f5 --- /dev/null +++ b/src/main/java/net/pterodactylus/demoscenemusic/template/TrackDerivativeAccessor.java @@ -0,0 +1,47 @@ +/* + * DemosceneMusic - TrackDerivativeAccessor.java - Copyright © 2012 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.demoscenemusic.template; + +import net.pterodactylus.demoscenemusic.core.Core; +import net.pterodactylus.demoscenemusic.data.TrackDerivative; +import net.pterodactylus.util.template.ReflectionAccessor; +import net.pterodactylus.util.template.TemplateContext; + +/** + * {@link ReflectionAccessor} implementation that adds “size” and “path” + * properties to a {@link TrackDerivative}. + * + * @author David ‘Bombe’ Roden + */ +public class TrackDerivativeAccessor extends ReflectionAccessor { + + /** + * {@inheritDoc} + */ + @Override + public Object get(TemplateContext templateContext, Object object, String member) { + TrackDerivative trackDerivative = (TrackDerivative) object; + if ("path".equals(member)) { + return ((Core) templateContext.get("core")).getDataDirectory().getPath(trackDerivative.getId()); + } else if ("size".equals(member)) { + return ((Core) templateContext.get("core")).getDataDirectory().getFile(trackDerivative.getId()).length(); + } + return super.get(templateContext, object, member); + } + +} -- 2.7.4 From 1b616c89a6518af37a55f35123e2252658fa56b2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 01:37:19 +0200 Subject: [PATCH 05/16] Add match filter to templates. --- .../java/net/pterodactylus/demoscenemusic/core/TemplateServlet.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/core/TemplateServlet.java b/src/main/java/net/pterodactylus/demoscenemusic/core/TemplateServlet.java index df753f1..a159e8a 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/core/TemplateServlet.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/core/TemplateServlet.java @@ -52,6 +52,7 @@ import net.pterodactylus.util.io.StreamCopier; import net.pterodactylus.util.template.ClassPathTemplateProvider; import net.pterodactylus.util.template.CollectionSortFilter; import net.pterodactylus.util.template.HtmlFilter; +import net.pterodactylus.util.template.MatchFilter; import net.pterodactylus.util.template.ReflectionAccessor; import net.pterodactylus.util.template.Template; import net.pterodactylus.util.template.TemplateContextFactory; @@ -68,6 +69,7 @@ import net.pterodactylus.util.web.Response; public class TemplateServlet extends HttpServlet { private Core core; + private final TemplateContextFactory templateContextFactory = new TemplateContextFactory(); private final Map> pages = new HashMap>(); @@ -116,6 +118,7 @@ public class TemplateServlet extends HttpServlet { }); templateContextFactory.addFilter("sort", sortFilter); + templateContextFactory.addFilter("matches", new MatchFilter()); templateContextFactory.addTemplateObject("core", core); templateContextFactory.addTemplateObject("dataManager", core.getDataManager()); -- 2.7.4 From 278bcc6a8c05363a6d157076e0a018f004803746 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 01:39:06 +0200 Subject: [PATCH 06/16] Add method to save a track with artists and properties. --- .../demoscenemusic/data/DataManager.java | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java b/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java index 5f20905..6499603 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java @@ -38,6 +38,7 @@ import net.pterodactylus.util.database.Join.JoinType; import net.pterodactylus.util.database.ObjectCreator; import net.pterodactylus.util.database.ObjectCreator.StringCreator; import net.pterodactylus.util.database.OrderField; +import net.pterodactylus.util.database.Parameter.IntegerParameter; import net.pterodactylus.util.database.Parameter.StringParameter; import net.pterodactylus.util.database.Query; import net.pterodactylus.util.database.Query.Type; @@ -392,6 +393,36 @@ public class DataManager { } /** + * Saves the given track. This also saves all relationships of the track. + * + * @param track + * The track to save + * @throws DatabaseException + * if a database error occurs + */ + public void saveTrack(Track track) throws DatabaseException { + Query query = new Query(Type.UPDATE, "TRACKS"); + query.addValueField(new ValueField("TRACKS.NAME", new StringParameter(track.getName()))); + query.addValueField(new ValueField("TRACKS.REMIX", new StringParameter(track.getRemix()))); + query.addWhereClause(new ValueFieldWhereClause(new ValueField("TRACKS.ID", new StringParameter(track.getId())))); + database.update(query); + /* store artist information. */ + track.getArtists(); /* prefetch artists. */ + query = new Query(Type.DELETE, "TRACK_ARTISTS"); + query.addWhereClause(new ValueFieldWhereClause(new ValueField("TRACK_ARTISTS.TRACK", new StringParameter(track.getId())))); + database.update(query); + for (int index = 0; index < track.getArtists().size(); ++index) { + query = new Query(Type.INSERT, "TRACK_ARTISTS"); + query.addValueField(new ValueField("TRACK_ARTISTS.TRACK", new StringParameter(track.getId()))); + query.addValueField(new ValueField("TRACK_ARTISTS.ARTIST", new StringParameter(track.getArtists().get(index).getId()))); + query.addValueField(new ValueField("TRACK_ARTISTS.DISPLAY_ORDER", new IntegerParameter(index + 1))); + database.insert(query); + } + /* store properties. */ + saveProperties(track.getProperties(), "TRACK_PROPERTIES", "TRACK", track.getId()); + } + + /** * Returns the derivative with the given ID. * * @param id @@ -603,6 +634,7 @@ public class DataManager { /** Memoizer for the tracks by this artist. */ private final Memoizer tracksMemoizer = new Memoizer(new Callable() { + @Override public Void call() throws DatabaseException { if (!hasValue("tracks")) { @@ -814,6 +846,7 @@ public class DataManager { } return null; } + }); /** -- 2.7.4 From 62bd730cd38294909f778b3b273867931c7d5cad Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 01:39:25 +0200 Subject: [PATCH 07/16] Automatically link new track to an artist. --- .../net/pterodactylus/demoscenemusic/page/admin/AddTrackPage.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AddTrackPage.java b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AddTrackPage.java index e0c8e7f..2234449 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AddTrackPage.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AddTrackPage.java @@ -18,6 +18,7 @@ package net.pterodactylus.demoscenemusic.page.admin; import net.pterodactylus.demoscenemusic.core.Core; +import net.pterodactylus.demoscenemusic.data.Artist; import net.pterodactylus.demoscenemusic.data.Track; import net.pterodactylus.demoscenemusic.page.ServletRequest; import net.pterodactylus.util.database.DatabaseException; @@ -66,7 +67,14 @@ public class AddTrackPage extends AdminBasePage { return; } try { + String artistId = request.getServletRequest().getParameter("artist"); + Artist artist = getCore().getDataManager().getArtistById(artistId); + if (artist == null) { + templateContext.set("error", "no-artist-given"); + } Track track = getCore().getDataManager().createTrack(name); + track.getArtists().add(artist); + getCore().getDataManager().saveTrack(track); throw new RedirectException("admin.edit-track?id=" + track.getId()); } catch (DatabaseException de1) { throw new RuntimeException("Could not create track.", de1); -- 2.7.4 From d576410064fdbeaad90379ce484473ea1cad504b Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 11:21:10 +0200 Subject: [PATCH 08/16] Redirect back to itself after editing. --- .../java/net/pterodactylus/demoscenemusic/page/admin/EditTrackPage.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditTrackPage.java b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditTrackPage.java index def00fb..c1f999f 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditTrackPage.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditTrackPage.java @@ -77,6 +77,7 @@ public class EditTrackPage extends AdminBasePage { processProperties(request, track); getCore().getDataManager().saveTrack(track); + throw new RedirectException("admin.edit-track?id=" + track.getId()); } } catch (DatabaseException de1) { throw new RuntimeException("Could not edit track.", de1); -- 2.7.4 From ab171583f8680b47b35699bacafb6a1f65563571 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 11:24:08 +0200 Subject: [PATCH 09/16] Always keep the properties sorted. --- src/main/java/net/pterodactylus/demoscenemusic/data/Properties.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/data/Properties.java b/src/main/java/net/pterodactylus/demoscenemusic/data/Properties.java index 3b72223..74bf524 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/data/Properties.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/data/Properties.java @@ -17,10 +17,10 @@ package net.pterodactylus.demoscenemusic.data; -import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +import java.util.TreeMap; /** * Container for custom properties that can be attached to all data containers. @@ -31,7 +31,7 @@ import java.util.Map.Entry; public class Properties implements Iterable> { /** The properties. */ - private final Map properties = new HashMap(); + private final Map properties = new TreeMap(); /** The “dirty” flag. */ private boolean dirty = false; -- 2.7.4 From 7bae34cd2768314df3c169da542c2403161be3a1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 11:46:59 +0200 Subject: [PATCH 10/16] Add method to save track derivatives. --- .../net/pterodactylus/demoscenemusic/data/DataManager.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java b/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java index 6499603..ad01bfe 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java @@ -502,6 +502,19 @@ public class DataManager { } /** + * Saves the given track derivative. As a track derivative does not have any + * attributes of its own only its properties are saved. + * + * @param trackDerivative + * The track derivative to save + * @throws DatabaseException + * if a database error occurs + */ + public void saveTrackDerivate(TrackDerivative trackDerivative) throws DatabaseException { + saveProperties(trackDerivative.getProperties(), "TRACK_DERIVATIVE_PROPERTIES", "TRACK_DERIVATIVE", trackDerivative.getId()); + } + + /** * Returns all groups the artist with the given ID belongs to. * * @param artistId -- 2.7.4 From 06787f727a401ed8cc4c3ecd23936bf40a8b7531 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 11:48:59 +0200 Subject: [PATCH 11/16] Improve directory name generation. --- .../demoscenemusic/core/DataDirectory.java | 36 ++++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/core/DataDirectory.java b/src/main/java/net/pterodactylus/demoscenemusic/core/DataDirectory.java index 63c2933..1574f73 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/core/DataDirectory.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/core/DataDirectory.java @@ -47,7 +47,7 @@ public class DataDirectory { * @return The absolute path of the file */ public String getPath(String id) { - return new File(dataDirectory, id.toLowerCase().replace('-', '/')).getAbsolutePath(); + return new File(new File(dataDirectory, getDirectoryName(id)), getFileName(id)).getAbsolutePath(); } /** @@ -59,9 +59,39 @@ public class DataDirectory { * @return The file */ public File getFile(String id) { - File file = new File(dataDirectory, id.toLowerCase().replace('-', '/')); + File file = new File(dataDirectory, getDirectoryName(id)); file.mkdirs(); - return file; + return new File(file, getFileName(id)); + } + + // + // PRIVATE METHODS + // + + /** + * Returns the relative name of the directory that the file for the given ID + * will be stored in. + * + * @param id + * The ID of the file to store + * @return The name of the directory to store the file in + */ + private String getDirectoryName(String id) { + String realId = id.replaceAll("-", "").toLowerCase(); + return realId.substring(0, 2) + "/" + realId.substring(2, 4) + "/" + realId.substring(4, 6) + "/" + realId.substring(6, 8); + } + + /** + * Returns the name of the file for the given ID, relative to its + * {@link #getDirectoryName(String) directory}. + * + * @param id + * The ID of the file to store + * @return The name of the file to store the file in + */ + private String getFileName(String id) { + String realId = id.replaceAll("-", "").toLowerCase(); + return realId.substring(8); } } -- 2.7.4 From 565ad78c862c9fefcba5fb35fd07e6d2a25746a1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 12:10:22 +0200 Subject: [PATCH 12/16] Add method to remove a file and all of its empty parent directories. --- .../demoscenemusic/core/DataDirectory.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/core/DataDirectory.java b/src/main/java/net/pterodactylus/demoscenemusic/core/DataDirectory.java index 1574f73..faa169e 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/core/DataDirectory.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/core/DataDirectory.java @@ -64,6 +64,25 @@ public class DataDirectory { return new File(file, getFileName(id)); } + /** + * Removes the file and all its directories, up to the + * {@link #dataDirectory}. + * + * @param id + * The ID of the file to remove + */ + public void removeFile(String id) { + File file = getFile(id); + if (file.delete()) { + File parentDirectory = file.getParentFile(); + String lastDirectory = new File(dataDirectory).getAbsolutePath(); + while (!lastDirectory.equals(parentDirectory.getAbsolutePath()) && (parentDirectory.listFiles().length == 0)) { + parentDirectory.delete(); + parentDirectory = parentDirectory.getParentFile(); + } + } + } + // // PRIVATE METHODS // -- 2.7.4 From 213e80871a5f574d7ee048a87fb1974fe4716d5c Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 12:10:31 +0200 Subject: [PATCH 13/16] Add method to remove a derivative from the database. --- .../pterodactylus/demoscenemusic/data/DataManager.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java b/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java index ad01bfe..31e5def 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java @@ -515,6 +515,23 @@ public class DataManager { } /** + * Removes the given track derivative and all its properties from the + * database. + * + * @param trackDerivative + * The track derivative to remove + * @throws DatabaseException + * if a database error occurs + */ + public void removeTrackDerivative(TrackDerivative trackDerivative) throws DatabaseException { + Query query = new Query(Type.DELETE, "TRACK_DERIVATIVES"); + query.addWhereClause(new ValueFieldWhereClause(new ValueField("TRACK_DERIVATIVES.ID", new StringParameter(trackDerivative.getId())))); + database.update(query); + /* remove the properties. */ + saveProperties(new Properties(), "TRACK_DERIVATIVE_PROPERTIES", "TRACK_DERIVATIVE", trackDerivative.getId()); + } + + /** * Returns all groups the artist with the given ID belongs to. * * @param artistId -- 2.7.4 From b2ab3fd2aefa2815f8c55b5b0e8b8d2eb912a192 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 12:12:35 +0200 Subject: [PATCH 14/16] Clear properties are not saved, so make them dirty. --- src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java b/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java index 31e5def..c0001c4 100644 --- a/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java +++ b/src/main/java/net/pterodactylus/demoscenemusic/data/DataManager.java @@ -528,7 +528,7 @@ public class DataManager { query.addWhereClause(new ValueFieldWhereClause(new ValueField("TRACK_DERIVATIVES.ID", new StringParameter(trackDerivative.getId())))); database.update(query); /* remove the properties. */ - saveProperties(new Properties(), "TRACK_DERIVATIVE_PROPERTIES", "TRACK_DERIVATIVE", trackDerivative.getId()); + saveProperties(new Properties().set("dirty", "true").removeAll(), "TRACK_DERIVATIVE_PROPERTIES", "TRACK_DERIVATIVE", trackDerivative.getId()); } /** -- 2.7.4 From 89374975e400fb63e2c0a8e68986c98ed76bd711 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 12:16:38 +0200 Subject: [PATCH 15/16] Add page that lets the user add a derivative. --- .../page/admin/AddTrackDerivativePage.java | 154 +++++++++++++++++++++ src/main/resources/templates/admin.add-derivative | 12 ++ src/main/webapp/WEB-INF/web.xml.template | 4 + 3 files changed, 170 insertions(+) create mode 100644 src/main/java/net/pterodactylus/demoscenemusic/page/admin/AddTrackDerivativePage.java create mode 100644 src/main/resources/templates/admin.add-derivative diff --git a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AddTrackDerivativePage.java b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AddTrackDerivativePage.java new file mode 100644 index 0000000..579940c --- /dev/null +++ b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/AddTrackDerivativePage.java @@ -0,0 +1,154 @@ +/* + * DemosceneMusic - UploadTrackPage.java - Copyright © 2012 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.demoscenemusic.page.admin; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + +import net.pterodactylus.demoscenemusic.core.Core; +import net.pterodactylus.demoscenemusic.data.Track; +import net.pterodactylus.demoscenemusic.data.TrackDerivative; +import net.pterodactylus.demoscenemusic.page.ServletRequest; +import net.pterodactylus.util.database.DatabaseException; +import net.pterodactylus.util.io.Closer; +import net.pterodactylus.util.io.StreamCopier; +import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; +import net.pterodactylus.util.template.TemplateContextFactory; +import net.pterodactylus.util.web.Method; +import net.pterodactylus.util.web.RedirectException; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; + +/** + * This page lets the user upload a {@link TrackDerivative} for a {@link Track}. + * + * @author David ‘Bombe’ Roden + */ +public class AddTrackDerivativePage extends AdminBasePage { + + /** + * Creates a new upload-track-derivative page. + * + * @param core + * The core + * @param templateContextFactory + * The template context factory + * @param template + * The template to render + */ + public AddTrackDerivativePage(Core core, TemplateContextFactory templateContextFactory, Template template) { + super(core, templateContextFactory, template, "admin.upload-track"); + } + + // + // BASEPAGE METHODS + // + + /** + * {@inheritDoc} + */ + @Override + protected void processTemplate(TemplateContext templateContext, ServletRequest request) throws RedirectException { + super.processTemplate(templateContext, request); + if (request.getMethod() == Method.POST) { + + try { + + Track track = null; + File destinationFile = null; + String filename = null; + + try { + @SuppressWarnings("unchecked") + List fileItems = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request.getServletRequest()); + for (FileItem fileItem : fileItems) { + if (!fileItem.isFormField()) { + filename = fileItem.getName(); + destinationFile = File.createTempFile("demoscenemusic.", ".data"); + InputStream fileInputStream = fileItem.getInputStream(); + OutputStream destinationOutputStream = new FileOutputStream(destinationFile); + try { + StreamCopier.copy(fileInputStream, destinationOutputStream); + } finally { + Closer.close(destinationOutputStream); + Closer.close(fileInputStream); + } + } else { + if (fileItem.getFieldName().equals("track")) { + String trackId = fileItem.getString("UTF-8"); + track = getCore().getDataManager().getTrackById(trackId); + } + } + } + + if (track == null) { + templateContext.set("error", "no-track-given"); + return; + } + + if ((filename == null) || (destinationFile == null)) { + /* no file has been uploaded. */ + templateContext.set("error", "no-file-uploaded"); + return; + } + + /* okay, we’re here, so everything’s fine, probably. */ + TrackDerivative derivative = getCore().getDataManager().createTrackDerivative(track); + derivative.getProperties().set("file.original-name", filename); + getCore().getDataManager().saveTrackDerivate(derivative); + + /* copy the file again. */ + File finalFile = getCore().getDataDirectory().getFile(derivative.getId()); + FileOutputStream finalOutputStream = new FileOutputStream(finalFile); + FileInputStream tempInputStream = new FileInputStream(destinationFile); + try { + StreamCopier.copy(tempInputStream, finalOutputStream); + } finally { + Closer.close(tempInputStream); + Closer.close(finalOutputStream); + } + + /* back to editing the track! */ + throw new RedirectException("admin.edit-track?id=" + track.getId()); + + } finally { + if (destinationFile != null) { + destinationFile.delete(); + } + } + + } catch (FileUploadException fue1) { + throw new RuntimeException("Could not upload file.", fue1); + } catch (IOException ioe1) { + throw new RuntimeException("Could not upload file.", ioe1); + } catch (DatabaseException de1) { + throw new RuntimeException("Could not upload file.", de1); + } + } + } + +} diff --git a/src/main/resources/templates/admin.add-derivative b/src/main/resources/templates/admin.add-derivative new file mode 100644 index 0000000..91751b1 --- /dev/null +++ b/src/main/resources/templates/admin.add-derivative @@ -0,0 +1,12 @@ +<%include include/header title=="Add Track Derivative"> + +

Add a New Track Derivative

+ +<%if error|matches value=="no-track-given"> +

You did not specify a track.

+<%/if> +<%if error|matches value=="no-file-uploaded"> +

You did not select a file.

+<%/if> + +<%include include/footer> \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml.template b/src/main/webapp/WEB-INF/web.xml.template index 48dda54..9c8b1c0 100644 --- a/src/main/webapp/WEB-INF/web.xml.template +++ b/src/main/webapp/WEB-INF/web.xml.template @@ -71,6 +71,10 @@ net.pterodactylus.demoscenemusic.page.admin.AddTrackPage + admin.add-derivative + net.pterodactylus.demoscenemusic.page.admin.AddTrackDerivativePage + + admin.artists net.pterodactylus.demoscenemusic.page.admin.ArtistsAdminPage -- 2.7.4 From aaf778ed0855e0b21b9801c48ed44892583e8425 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sat, 28 Jul 2012 12:17:02 +0200 Subject: [PATCH 16/16] Add page that lets the user edit a track derivative. --- .../page/admin/EditDerivativePage.java | 87 ++++++++++++++++++++++ src/main/resources/templates/admin.edit-derivative | 0 src/main/webapp/WEB-INF/web.xml.template | 4 + 3 files changed, 91 insertions(+) create mode 100644 src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditDerivativePage.java create mode 100644 src/main/resources/templates/admin.edit-derivative diff --git a/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditDerivativePage.java b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditDerivativePage.java new file mode 100644 index 0000000..8c97a84 --- /dev/null +++ b/src/main/java/net/pterodactylus/demoscenemusic/page/admin/EditDerivativePage.java @@ -0,0 +1,87 @@ +/* + * DemosceneMusic - EditDerivativePage.java - Copyright © 2012 David Roden + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.pterodactylus.demoscenemusic.page.admin; + +import net.pterodactylus.demoscenemusic.core.Core; +import net.pterodactylus.demoscenemusic.data.Track; +import net.pterodactylus.demoscenemusic.data.TrackDerivative; +import net.pterodactylus.demoscenemusic.page.ServletRequest; +import net.pterodactylus.util.database.DatabaseException; +import net.pterodactylus.util.template.Template; +import net.pterodactylus.util.template.TemplateContext; +import net.pterodactylus.util.template.TemplateContextFactory; +import net.pterodactylus.util.web.Method; +import net.pterodactylus.util.web.RedirectException; + +/** + * Page that lets a user edit a derivative. + * + * @author David ‘Bombe’ Roden + */ +public class EditDerivativePage extends AdminBasePage { + + /** + * Creates a new edit-derivative page. + * + * @param core + * The core + * @param templateContextFactory + * The template context factory + * @param template + * The template to render + */ + public EditDerivativePage(Core core, TemplateContextFactory templateContextFactory, Template template) { + super(core, templateContextFactory, template, "admin.edit-derivative"); + } + + // + // BASEPAGE METHODS + // + + /** + * {@inheritDoc} + */ + @Override + protected void processTemplate(TemplateContext templateContext, ServletRequest request) throws RedirectException { + super.processTemplate(templateContext, request); + if (request.getMethod() == Method.POST) { + + try { + + String trackId = request.getServletRequest().getParameter("track"); + Track track = getCore().getDataManager().getTrackById(trackId); + String derivativeId = request.getServletRequest().getParameter("derivative"); + TrackDerivative derivative = getCore().getDataManager().getTrackDerivativeById(derivativeId); + + if ("true".equals(request.getServletRequest().getParameter("delete"))) { + getCore().getDataDirectory().removeFile(derivativeId); + getCore().getDataManager().removeTrackDerivative(derivative); + throw new RedirectException("admin.edit-track?id=" + track.getId()); + } + + processProperties(request, derivative); + getCore().getDataManager().saveTrackDerivate(derivative); + throw new RedirectException("admin.edit-track?id=" + track.getId()); + + } catch (DatabaseException de1) { + throw new RuntimeException("Could not edit derivative.", de1); + } + } + } + +} diff --git a/src/main/resources/templates/admin.edit-derivative b/src/main/resources/templates/admin.edit-derivative new file mode 100644 index 0000000..e69de29 diff --git a/src/main/webapp/WEB-INF/web.xml.template b/src/main/webapp/WEB-INF/web.xml.template index 9c8b1c0..573d063 100644 --- a/src/main/webapp/WEB-INF/web.xml.template +++ b/src/main/webapp/WEB-INF/web.xml.template @@ -83,6 +83,10 @@ net.pterodactylus.demoscenemusic.page.admin.EditArtistPage + admin.edit-derivative + net.pterodactylus.demoscenemusic.page.admin.EditDerivativePage + + admin.edit-track net.pterodactylus.demoscenemusic.page.admin.EditTrackPage -- 2.7.4