This is an automated email from the git hooks/post-receive script. New commit to branch feature/1110 in repository pollen. See http://git.chorem.org/pollen.git commit cbcdfbef7e7e4d6bd995cc180bbf6950ebde5e9a Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 20 12:18:20 2014 +0200 refs #1110 store and load are ok --- pollen-io-api/pom.xml | 6 + .../org/chorem/pollen/io/ExportServiceApi.java | 14 -- .../org/chorem/pollen/io/ImportServiceApi.java | 11 -- .../org/chorem/pollen/io/PollenDataStorage.java | 198 ++++++++++++++++++--- .../main/java/org/chorem/pollen/io/dto/Poll.java | 13 +- .../java/org/chorem/pollen/io/dto/PollenData.java | 44 ++++- .../org/chorem/pollen/io/dto/PollenResource.java | 13 +- .../chorem/pollen/io/dto/PollenResourceFile.java | 28 +++ .../pollen/io/dto/PollenResourceZipEntry.java | 35 ++++ .../main/java/org/chorem/pollen/io/dto/Vote.java | 10 +- .../org/chorem/pollen/io/dto/VoterListMember.java | 10 -- .../chorem/pollen/io/PollenDataStorageTest.java | 33 +++- pollen-io-api/src/test/resources/resource1.txt | 1 + .../src/test/resources/resource2.properties | 1 + pollen-io-api/src/test/resources/store.zip | Bin 604 -> 1572 bytes 15 files changed, 338 insertions(+), 79 deletions(-) diff --git a/pollen-io-api/pom.xml b/pollen-io-api/pom.xml index 3267442..bdf5cdd 100644 --- a/pollen-io-api/pom.xml +++ b/pollen-io-api/pom.xml @@ -17,6 +17,11 @@ <dependencies> <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + + <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> @@ -34,6 +39,7 @@ <dependency> <groupId>org.nuiton</groupId> <artifactId>nuiton-utils</artifactId> + <scope>test</scope> </dependency> <dependency> diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/ExportServiceApi.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/ExportServiceApi.java deleted file mode 100644 index 142dec6..0000000 --- a/pollen-io-api/src/main/java/org/chorem/pollen/io/ExportServiceApi.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.chorem.pollen.io; - -import org.chorem.pollen.io.dto.Poll; -import org.chorem.pollen.io.dto.PollenData; -import org.chorem.pollen.io.dto.PollenUser; - -import java.io.File; -import java.util.Set; - -public interface ExportServiceApi { - - void exportData(PollenData data, File zipFile); - -} diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/ImportServiceApi.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/ImportServiceApi.java deleted file mode 100644 index b28bbfa..0000000 --- a/pollen-io-api/src/main/java/org/chorem/pollen/io/ImportServiceApi.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.chorem.pollen.io; - -import org.chorem.pollen.io.dto.PollenData; - -import java.io.File; - -public interface ImportServiceApi { - - PollenData importData(File zipFile); - -} diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/PollenDataStorage.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/PollenDataStorage.java index 388d041..a0b59de 100644 --- a/pollen-io-api/src/main/java/org/chorem/pollen/io/PollenDataStorage.java +++ b/pollen-io-api/src/main/java/org/chorem/pollen/io/PollenDataStorage.java @@ -1,5 +1,6 @@ package org.chorem.pollen.io; +import com.google.common.collect.ImmutableSet; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; @@ -20,14 +21,23 @@ import org.apache.commons.logging.LogFactory; import org.chorem.pollen.io.dto.Id; import org.chorem.pollen.io.dto.Poll; import org.chorem.pollen.io.dto.PollenData; +import org.chorem.pollen.io.dto.PollenResource; +import org.chorem.pollen.io.dto.PollenResourceZipEntry; import org.chorem.pollen.io.dto.PollenUser; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; import java.util.Date; import java.util.Enumeration; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; @@ -54,14 +64,19 @@ public class PollenDataStorage { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setExclusionStrategies(new ExclusionStrategy() { + + Set<String> skipFiledNames = ImmutableSet.copyOf(new String[]{"polls", "users", "resources"}); + + Set<Class<?>> skipTypes = ImmutableSet.copyOf(new Class<?>[]{ZipFile.class, ZipEntry.class, File.class}); + @Override public boolean shouldSkipField(FieldAttributes f) { - return false; + return skipFiledNames.contains(f.getName()); } @Override public boolean shouldSkipClass(Class<?> clazz) { - return clazz == Class.class; + return skipTypes.contains(clazz); } }); @@ -111,6 +126,8 @@ public class PollenDataStorage { try (ZipOutputStream outputStream = new ZipOutputStream(FileUtils.openOutputStream(zipFile))) { + storeMetas(data, outputStream); + for (Poll poll : data.getPolls()) { store("polls", poll, outputStream); @@ -123,50 +140,155 @@ public class PollenDataStorage { } + for (PollenResource resource : data.getResources()) { + + store("resources", resource, outputStream); + + } + } } public PollenData load(File zipFile) throws IOException { - PollenData data = new PollenData(); + Pattern resourcePattern = Pattern.compile("resources\\/(.+)?\\.(meta|content)?"); try (ZipFile zip = new ZipFile(zipFile)) { - { // first pass to get users - Enumeration<? extends ZipEntry> entries = zip.entries(); - while (entries.hasMoreElements()) { - ZipEntry zipEntry = entries.nextElement(); - String name = zipEntry.getName(); - if (name.startsWith("users")) { + Set<String> userEntries = new LinkedHashSet<>(); + Set<String> pollEntries = new LinkedHashSet<>(); + Set<String> resourceEntries = new LinkedHashSet<>(); - PollenUser pollenUser = load(zip, zipEntry, PollenUser.class); - data.addUser(pollenUser); + Enumeration<? extends ZipEntry> entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry zipEntry = entries.nextElement(); + String name = zipEntry.getName(); + if (name.startsWith("users")) { - } - } - } + userEntries.add(name); - { // second pass to get polls - Enumeration<? extends ZipEntry> entries = zip.entries(); - while (entries.hasMoreElements()) { - ZipEntry zipEntry = entries.nextElement(); - String name = zipEntry.getName(); - if (name.startsWith("polls")) { + } else if (name.startsWith("polls")) { - Poll poll = load(zip, zipEntry, Poll.class); - data.addPoll(poll); + pollEntries.add(name); + + } else if (name.startsWith("resources")) { + + Matcher matcher = resourcePattern.matcher(name); + if (matcher.matches()) { + + String id = matcher.group(1); + + resourceEntries.add("resources/" + id); + + } else { + + if (log.isWarnEnabled()) { + log.warn("Could not match resource: " + name); + } } } + } + PollenData data = loadMetas(zip); + + loadUsers(zip, userEntries, data); + loadPolls(zip, pollEntries, data); + loadResources(zip, resourceEntries, data); + + return data; + } + } + + protected PollenData loadMetas(ZipFile zip) throws IOException { + + ZipEntry zipEntry = zip.getEntry("meta"); + PollenData data = load(zip, zipEntry, PollenData.class); return data; } + protected void loadUsers(ZipFile zip, Set<String> zipEntryNames, PollenData data) throws IOException { + + for (String zipEntryName : zipEntryNames) { + + ZipEntry zipEntry = zip.getEntry(zipEntryName); + PollenUser pollenUser = load(zip, zipEntry, PollenUser.class); + data.addUser(pollenUser); + + } + + } + + protected void loadPolls(ZipFile zip, Set<String> zipEntryNames, PollenData data) throws IOException { + + for (String zipEntryName : zipEntryNames) { + + ZipEntry zipEntry = zip.getEntry(zipEntryName); + Poll poll = load(zip, zipEntry, Poll.class); + data.addPoll(poll); + + } + + } + + protected void loadResources(ZipFile zip, Set<String> zipEntryNames, PollenData data) throws IOException { + + for (String zipEntryName : zipEntryNames) { + + // load meta + ZipEntry zipEntryMeta = zip.getEntry(zipEntryName + ".meta"); + PollenResourceZipEntry resource = load(zip, zipEntryMeta, PollenResourceZipEntry.class); + + resource.setZipFile(zip); + resource.setZipEntryName(zipEntryName + ".content"); + + data.addResource(resource); + + } + + } + + public class ZipURLStreamHandler extends URLStreamHandler { + public ZipURLStreamHandler() { + } + + public URLConnection openConnection(final URL u) throws IOException { + + if ("zip".equals(u.getProtocol())) { + return new URLConnection(u) { + + URL url = u; + + + @Override + public void connect() throws IOException { + + } + }; + } + return null; + } + } + + protected void storeMetas(PollenData data, ZipOutputStream outputStream) throws IOException { + + ZipEntry zipEntry = new ZipEntry("meta"); + outputStream.putNextEntry(zipEntry); + + String json = toJson(data); + + if (log.isDebugEnabled()) { + log.debug("Store entry: " + zipEntry.getName()); + } + IOUtils.write(json, outputStream); + + } + protected void store(String prefix, Id id, ZipOutputStream outputStream) throws IOException { ZipEntry zipEntry = new ZipEntry(prefix + "/" + id.getId()); @@ -181,7 +303,37 @@ public class PollenDataStorage { } - protected <O extends Id> O load(ZipFile zip, ZipEntry zipEntry, Class<O> type) throws IOException { + protected void store(String prefix, PollenResource resource, ZipOutputStream outputStream) throws IOException { + + // store resource metas + { + ZipEntry zipEntry = new ZipEntry(prefix + "/" + resource.getId() + ".meta"); + outputStream.putNextEntry(zipEntry); + + if (log.isDebugEnabled()) { + log.debug("Store entry: " + zipEntry.getName()); + } + String json = toJson(resource); + IOUtils.write(json, outputStream); + } + + // store resource content + { + ZipEntry zipEntry = new ZipEntry(prefix + "/" + resource.getId() + ".content"); + outputStream.putNextEntry(zipEntry); + + if (log.isDebugEnabled()) { + log.debug("Store entry: " + zipEntry.getName()); + } + + try (InputStream inputStream = resource.openStream()) { + IOUtils.copy(inputStream, outputStream); + } + } + + } + + protected <O> O load(ZipFile zip, ZipEntry zipEntry, Class<O> type) throws IOException { try (InputStream inputStream = zip.getInputStream(zipEntry)) { diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/Poll.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/Poll.java index 6274071..6f2934d 100644 --- a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/Poll.java +++ b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/Poll.java @@ -6,7 +6,6 @@ import java.util.Set; public class Poll extends Id { - protected String title; protected String description; @@ -47,10 +46,13 @@ public class Poll extends Id { protected final Set<Comment> comments; + protected final Set<Vote> votes; + public Poll() { voterLists = new LinkedHashSet<>(); choices = new LinkedHashSet<>(); comments = new LinkedHashSet<>(); + votes = new LinkedHashSet<>(); } public String getTitle() { @@ -214,4 +216,13 @@ public class Poll extends Id { comments.add(comment); } + public Set<Vote> getVotes() { + return votes; + } + + public void addVote(Vote vote) { + votes.add(vote); + } + + } diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenData.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenData.java index 76e8c64..935a273 100644 --- a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenData.java +++ b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenData.java @@ -1,7 +1,6 @@ package org.chorem.pollen.io.dto; -import org.nuiton.util.version.Version; - +import java.util.Date; import java.util.LinkedHashSet; import java.util.Set; @@ -13,12 +12,42 @@ import java.util.Set; */ public class PollenData { - protected Version version; + protected String description; + + protected Date date; + + protected String version; protected final Set<PollenUser> users = new LinkedHashSet<>(); protected final Set<Poll> polls = new LinkedHashSet<>(); + protected final Set<PollenResource> resources = new LinkedHashSet<>(); + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + public Set<PollenUser> getUsers() { return users; } @@ -34,5 +63,12 @@ public class PollenData { public void addPoll(Poll poll) { polls.add(poll); } - + + public Set<PollenResource> getResources() { + return resources; + } + + public void addResource(PollenResource resource) { + resources.add(resource); + } } diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResource.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResource.java index 9438920..d575032 100644 --- a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResource.java +++ b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResource.java @@ -1,8 +1,9 @@ package org.chorem.pollen.io.dto; -public class PollenResource { +import java.io.IOException; +import java.io.InputStream; - protected String resourceFilename; +public abstract class PollenResource extends Id { protected String contentType; @@ -10,13 +11,7 @@ public class PollenResource { protected long size; - public String getResourceFilename() { - return resourceFilename; - } - - public void setResourceFilename(String resourceFilename) { - this.resourceFilename = resourceFilename; - } + public abstract InputStream openStream() throws IOException; public String getContentType() { return contentType; diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResourceFile.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResourceFile.java new file mode 100644 index 0000000..f547e22 --- /dev/null +++ b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResourceFile.java @@ -0,0 +1,28 @@ +package org.chorem.pollen.io.dto; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +/** + * Created on 9/20/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 2.0 + */ +public class PollenResourceFile extends PollenResource { + + protected File file; + + public void setFile(File file) { + this.file = file; + } + + @Override + public InputStream openStream() throws FileNotFoundException { + FileInputStream inputStream = new FileInputStream(file); + return inputStream; + } + +} diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResourceZipEntry.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResourceZipEntry.java new file mode 100644 index 0000000..1fb299b --- /dev/null +++ b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/PollenResourceZipEntry.java @@ -0,0 +1,35 @@ +package org.chorem.pollen.io.dto; + +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * Created on 9/20/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 2.0 + */ +public class PollenResourceZipEntry extends PollenResource { + + protected ZipFile zipFile; + + protected String zipEntryName; + + public void setZipFile(ZipFile zipFile) { + this.zipFile = zipFile; + } + + public void setZipEntryName(String zipEntryName) { + this.zipEntryName = zipEntryName; + } + + @Override + public InputStream openStream() throws IOException { + ZipEntry entry = zipFile.getEntry(zipEntryName); + InputStream inputStream = zipFile.getInputStream(entry); + return inputStream; + } + +} diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/Vote.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/Vote.java index a9ed5e9..b6516fc 100644 --- a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/Vote.java +++ b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/Vote.java @@ -8,7 +8,7 @@ public class Vote { protected boolean anonymous; - protected Collection<VoteToChoice> voteToChoice; + protected Collection<VoteToChoice> voteToChoices; protected VoterListMember voterListMember; @@ -30,12 +30,12 @@ public class Vote { this.anonymous = anonymous; } - public Collection<VoteToChoice> getVoteToChoice() { - return voteToChoice; + public Collection<VoteToChoice> getVoteToChoices() { + return voteToChoices; } - public void setVoteToChoice(Collection<VoteToChoice> voteToChoice) { - this.voteToChoice = voteToChoice; + public void addVoteToChoice(VoteToChoice voteToChoice) { + voteToChoices.add(voteToChoice); } public VoterListMember getVoterListMember() { diff --git a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/VoterListMember.java b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/VoterListMember.java index 5542f04..6270079 100644 --- a/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/VoterListMember.java +++ b/pollen-io-api/src/main/java/org/chorem/pollen/io/dto/VoterListMember.java @@ -4,8 +4,6 @@ public class VoterListMember { protected double weight; - protected VoterList voterList; - protected PollenPrincipal member; public double getWeight() { @@ -16,14 +14,6 @@ public class VoterListMember { this.weight = weight; } - public VoterList getVoterList() { - return voterList; - } - - public void setVoterList(VoterList voterList) { - this.voterList = voterList; - } - public PollenPrincipal getMember() { return member; } diff --git a/pollen-io-api/src/test/java/org/chorem/pollen/io/PollenDataStorageTest.java b/pollen-io-api/src/test/java/org/chorem/pollen/io/PollenDataStorageTest.java index a804bed..a185d04 100644 --- a/pollen-io-api/src/test/java/org/chorem/pollen/io/PollenDataStorageTest.java +++ b/pollen-io-api/src/test/java/org/chorem/pollen/io/PollenDataStorageTest.java @@ -7,18 +7,21 @@ import org.apache.commons.logging.LogFactory; import org.chorem.pollen.io.dto.FavoriteList; import org.chorem.pollen.io.dto.FavoriteListMember; import org.chorem.pollen.io.dto.PollenData; +import org.chorem.pollen.io.dto.PollenResourceFile; import org.chorem.pollen.io.dto.PollenUser; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; +import org.nuiton.util.DateUtil; import org.nuiton.util.FileUtil; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.net.MalformedURLException; public class PollenDataStorageTest { @@ -71,7 +74,7 @@ public class PollenDataStorageTest { Assert.assertTrue(zipFile.exists()); -// saveResult(zipFile); + saveResult(zipFile); } @@ -96,10 +99,14 @@ public class PollenDataStorageTest { } - protected PollenData loadData() { + protected PollenData loadData() throws MalformedURLException { PollenData pollenData = new PollenData(); + pollenData.setDescription("Pollen Data"); + pollenData.setVersion("1.0"); + pollenData.setDate(DateUtil.createDate(20, 9, 2014)); + { PollenUser user = new PollenUser(); user.setId("user1"); @@ -191,6 +198,28 @@ public class PollenDataStorageTest { } } + + { + PollenResourceFile pollenResource = new PollenResourceFile(); + pollenResource.setId("pollenResource1"); + pollenResource.setName("pollenResource1"); + pollenResource.setSize(10); + pollenResource.setContentType("application/text"); + File resourceFile = new File(resourceDirectory, "resource1.txt"); + pollenResource.setFile(resourceFile); + pollenData.addResource(pollenResource); + } + { + PollenResourceFile pollenResource = new PollenResourceFile(); + pollenResource.setId("pollenResource2"); + pollenResource.setName("pollenResource2"); + pollenResource.setSize(10); + pollenResource.setContentType("application/text"); + File resourceFile = new File(resourceDirectory, "resource2.properties"); + pollenResource.setFile(resourceFile); + pollenData.addResource(pollenResource); + } + return pollenData; } diff --git a/pollen-io-api/src/test/resources/resource1.txt b/pollen-io-api/src/test/resources/resource1.txt new file mode 100644 index 0000000..be1903f --- /dev/null +++ b/pollen-io-api/src/test/resources/resource1.txt @@ -0,0 +1 @@ +Resource1 \ No newline at end of file diff --git a/pollen-io-api/src/test/resources/resource2.properties b/pollen-io-api/src/test/resources/resource2.properties new file mode 100644 index 0000000..559da33 --- /dev/null +++ b/pollen-io-api/src/test/resources/resource2.properties @@ -0,0 +1 @@ +Resource2=test \ No newline at end of file diff --git a/pollen-io-api/src/test/resources/store.zip b/pollen-io-api/src/test/resources/store.zip index b06f418..8c6d121 100644 Binary files a/pollen-io-api/src/test/resources/store.zip and b/pollen-io-api/src/test/resources/store.zip differ -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.