Removing redundant code
This commit is contained in:
parent
01e246023d
commit
4b91f0a6e3
15 changed files with 3 additions and 885 deletions
113
conf/resin.conf
113
conf/resin.conf
|
|
@ -1,113 +0,0 @@
|
||||||
<!--
|
|
||||||
- Resin 3.1 configuration file.
|
|
||||||
-->
|
|
||||||
<resin xmlns="http://caucho.com/ns/resin"
|
|
||||||
xmlns:resin="http://caucho.com/ns/resin/core">
|
|
||||||
|
|
||||||
<!--
|
|
||||||
- Logging configuration for the JDK logging API.
|
|
||||||
-->
|
|
||||||
<log name="" level="all" path="stdout:"
|
|
||||||
timestamp="[%H:%M:%S.%s] {%{thread}} "/>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
- 'info' for production
|
|
||||||
- 'fine' or 'finer' for development and troubleshooting
|
|
||||||
-->
|
|
||||||
<logger name="com.caucho" level="info"/>
|
|
||||||
|
|
||||||
<logger name="com.caucho.java" level="config"/>
|
|
||||||
<logger name="com.caucho.loader" level="config"/>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
- For production sites, change dependency-check-interval to something
|
|
||||||
- like 600s, so it only checks for updates every 10 minutes.
|
|
||||||
-->
|
|
||||||
<dependency-check-interval>2s</dependency-check-interval>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
- You can change the compiler to "javac", "eclipse" or "internal".
|
|
||||||
-->
|
|
||||||
<javac compiler="javac" args="-source 1.5"/>
|
|
||||||
|
|
||||||
<!-- Security providers.
|
|
||||||
- <security-provider>
|
|
||||||
- com.sun.net.ssl.internal.ssl.Provider
|
|
||||||
- </security-provider>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<cluster id="app-tier">
|
|
||||||
<!-- sets the content root for the cluster, relative to server.root -->
|
|
||||||
<root-directory>.</root-directory>
|
|
||||||
|
|
||||||
<server-default>
|
|
||||||
<!-- The http port -->
|
|
||||||
<http address="*" port="5080"/>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
- Configures the minimum free memory allowed before Resin
|
|
||||||
- will force a restart.
|
|
||||||
-->
|
|
||||||
<memory-free-min>1M</memory-free-min>
|
|
||||||
|
|
||||||
<!-- Maximum number of threads. -->
|
|
||||||
<thread-max>256</thread-max>
|
|
||||||
|
|
||||||
<!-- Configures the socket timeout -->
|
|
||||||
<socket-timeout>65s</socket-timeout>
|
|
||||||
|
|
||||||
<!-- Configures the keepalive -->
|
|
||||||
<keepalive-max>128</keepalive-max>
|
|
||||||
<keepalive-timeout>120s</keepalive-timeout>
|
|
||||||
</server-default>
|
|
||||||
|
|
||||||
<!-- define the servers in the cluster -->
|
|
||||||
<server id="" address="127.0.0.1" port="5079">
|
|
||||||
<watchdog-port>5078</watchdog-port>
|
|
||||||
<jvm-arg>-Djava.awt.headless=true</jvm-arg>
|
|
||||||
</server>
|
|
||||||
|
|
||||||
<!-- includes the web-app-default for default web-app behavior -->
|
|
||||||
<resin:import path="${resin.home}/conf/app-default.xml"/>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
- Default host configuration applied to all virtual hosts.
|
|
||||||
-->
|
|
||||||
<host-default>
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
- With another web server, like Apache, this can be commented out
|
|
||||||
- because the web server will log this information.
|
|
||||||
-->
|
|
||||||
<access-log path="build/access.log"
|
|
||||||
format='%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i"'
|
|
||||||
rollover-period="1W"/>
|
|
||||||
|
|
||||||
|
|
||||||
</host-default>
|
|
||||||
|
|
||||||
<!-- configures the default host, matching any host name -->
|
|
||||||
<host id=''>
|
|
||||||
|
|
||||||
<!-- configures the root web-app -->
|
|
||||||
<web-app id='/album' document-directory='webapp'>
|
|
||||||
|
|
||||||
<temp-dir>target/resin-tmp</temp-dir>
|
|
||||||
<work-dir>target/resin-work</work-dir>
|
|
||||||
|
|
||||||
<session-config>
|
|
||||||
<!-- 30 min timeout -->
|
|
||||||
<session-timeout>30</session-timeout>
|
|
||||||
</session-config>
|
|
||||||
|
|
||||||
<class-loader>
|
|
||||||
<compiling-loader path="target"/>
|
|
||||||
</class-loader>
|
|
||||||
|
|
||||||
<path-mapping url-pattern="/demo/*" real-path="${resin.root}/photos" />
|
|
||||||
</web-app>
|
|
||||||
|
|
||||||
</host>
|
|
||||||
</cluster>
|
|
||||||
</resin>
|
|
||||||
60
design.txt
60
design.txt
|
|
@ -1,60 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
|
||||||
=============
|
|
||||||
|
|
||||||
A (hidden) file exists in each album directory, holding information
|
|
||||||
about each image and each sub-album. For both images and albums the key is the
|
|
||||||
filename and the order in which each is listed determines the ordering
|
|
||||||
in the album. Common to both we have the following attributes:
|
|
||||||
|
|
||||||
- Caption, a text fragment explaining what's in the picture/album.
|
|
||||||
|
|
||||||
Special to images additional attributes stored are:
|
|
||||||
|
|
||||||
- Rotation (floating point number)
|
|
||||||
|
|
||||||
- Mask, represented by the four border sizes; top, left, bottom,
|
|
||||||
right. All floating point.
|
|
||||||
|
|
||||||
- Thumbnail mask. Same as above, but applies to thumbnail images.
|
|
||||||
As these are very small there may be a need to focus on a detail
|
|
||||||
of the original image to have a visual cue about the subject of
|
|
||||||
the photo.
|
|
||||||
|
|
||||||
For albums the additional attributes are:
|
|
||||||
|
|
||||||
- Cover picture, the picture (or album) representing the album as a
|
|
||||||
whole for the purpose of a thumbnail.
|
|
||||||
|
|
||||||
|
|
||||||
Web Interface
|
|
||||||
=============
|
|
||||||
|
|
||||||
The theory of operation is that the directory holding all the
|
|
||||||
subdirectories with albums maps to a webapp. The URLs accepted by the
|
|
||||||
webapp reflect the directory structure of the photo directories, but
|
|
||||||
adds some twists to make it possible to represent thumbnails, medium
|
|
||||||
sized images and large images in addition to the album pages
|
|
||||||
themselves. URLs for the albums are:
|
|
||||||
|
|
||||||
/album/index-num.html
|
|
||||||
|
|
||||||
There is a configuration switch indicating how many thumbnails to
|
|
||||||
show per album page. This makes "num" in index-num.html represent the
|
|
||||||
associated subset of images. There are also one picture per page
|
|
||||||
pages. These have the pattern:
|
|
||||||
|
|
||||||
/album/filename.html
|
|
||||||
|
|
||||||
The individual pictures are accessed with URLs like the following:
|
|
||||||
|
|
||||||
/album/.../size/filename.ext
|
|
||||||
|
|
||||||
In this URL size has to be one of the following: "thumb", "medium",
|
|
||||||
"large". The (global?) configuration determines the actual size
|
|
||||||
constraints for each of the sizes. Only certain file extentions are
|
|
||||||
supported. Notably "jpeg" and "png". "html" can not be allowed as it
|
|
||||||
would destroy the page per picture setup.
|
|
||||||
|
|
||||||
|
|
||||||
11
pom.xml
11
pom.xml
|
|
@ -70,12 +70,6 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.4</version>
|
|
||||||
<!-- <scope>test</scope> -->
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-core</artifactId>
|
<artifactId>spring-core</artifactId>
|
||||||
|
|
@ -101,11 +95,6 @@
|
||||||
<artifactId>commons-lang</artifactId>
|
<artifactId>commons-lang</artifactId>
|
||||||
<version>2.0</version>
|
<version>2.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>postgresql</groupId>
|
|
||||||
<artifactId>postgresql</artifactId>
|
|
||||||
<version>8.1-408.jdbc3</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>velocity</groupId>
|
<groupId>velocity</groupId>
|
||||||
<artifactId>velocity</artifactId>
|
<artifactId>velocity</artifactId>
|
||||||
|
|
|
||||||
117
project.xml
117
project.xml
|
|
@ -78,15 +78,6 @@
|
||||||
<war.bundle>true</war.bundle>
|
<war.bundle>true</war.bundle>
|
||||||
</properties>
|
</properties>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>postgresql</groupId>
|
|
||||||
<artifactId>postgresql</artifactId>
|
|
||||||
<version>8.1-408.jdbc3</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>true</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>velocity</groupId>
|
<groupId>velocity</groupId>
|
||||||
<artifactId>velocity</artifactId>
|
<artifactId>velocity</artifactId>
|
||||||
|
|
@ -129,114 +120,6 @@
|
||||||
<version>2.4</version>
|
<version>2.4</version>
|
||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.1</version>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>resin</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>resin-util</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>jta-101</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>webbeans-16</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>ejb-15</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>jpa-15</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>jsdk-15</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>hessian</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>jca-15</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>jstl-11</artifactId>
|
|
||||||
<version>3.1.5</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>resin-3.1</groupId>
|
|
||||||
<artifactId>resin-source</artifactId>
|
|
||||||
<type>source</type>
|
|
||||||
<jar>resin-3.1.5-src.zip</jar>
|
|
||||||
<properties>
|
|
||||||
<war.bundle>false</war.bundle>
|
|
||||||
</properties>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<sourceDirectory>src</sourceDirectory>
|
<sourceDirectory>src</sourceDirectory>
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
package org.forkalsrud.album.config;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
public class Album
|
|
||||||
extends Item
|
|
||||||
{
|
|
||||||
String frontPic;
|
|
||||||
|
|
||||||
Entry[] contents;
|
|
||||||
|
|
||||||
public Album(String name) {
|
|
||||||
super(name);
|
|
||||||
frontPic = null;
|
|
||||||
contents = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void scan(File dir)
|
|
||||||
{
|
|
||||||
File[] dirs = dir.listFiles(new FileFilter() {
|
|
||||||
public boolean accept(File f) {
|
|
||||||
return f.isDirectory();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
File[] files = dir.listFiles(new FilenameFilter() {
|
|
||||||
public boolean accept(File dir, String name) {
|
|
||||||
return name.endsWith(".JPEG")
|
|
||||||
|| name.endsWith(".jpeg")
|
|
||||||
|| name.endsWith(".JPG")
|
|
||||||
|| name.endsWith(".jpg");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
contents = new Entry[dirs.length + files.length];
|
|
||||||
int idx = 0;
|
|
||||||
|
|
||||||
for (File d : dirs) {
|
|
||||||
contents[idx++] = new Reference(d.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File f : files) {
|
|
||||||
contents[idx++] = new Photo(f.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eof
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package org.forkalsrud.album.config;
|
|
||||||
|
|
||||||
public abstract class Entry {
|
|
||||||
String name;
|
|
||||||
|
|
||||||
public Entry(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eof
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package org.forkalsrud.album.config;
|
|
||||||
|
|
||||||
|
|
||||||
public class Item
|
|
||||||
extends Entry
|
|
||||||
{
|
|
||||||
String caption;
|
|
||||||
boolean hidden;
|
|
||||||
|
|
||||||
public Item(String name) {
|
|
||||||
super(name);
|
|
||||||
caption = null;
|
|
||||||
hidden = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eof
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
package org.forkalsrud.album.config;
|
|
||||||
|
|
||||||
|
|
||||||
public class Photo
|
|
||||||
extends Item
|
|
||||||
{
|
|
||||||
Transform xform;
|
|
||||||
|
|
||||||
public Photo(String name) {
|
|
||||||
super(name);
|
|
||||||
xform = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// eof
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package org.forkalsrud.album.config;
|
|
||||||
|
|
||||||
public class Reference
|
|
||||||
extends Entry
|
|
||||||
{
|
|
||||||
public Reference(String name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eof
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package org.forkalsrud.album.config;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
public class Test
|
|
||||||
{
|
|
||||||
|
|
||||||
public static void main(String args[])
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
File dir = new File(args[0]);
|
|
||||||
|
|
||||||
Album a = new Album(dir.getName());
|
|
||||||
|
|
||||||
a.scan(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// eof
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package org.forkalsrud.album.config;
|
|
||||||
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Rectangle;
|
|
||||||
|
|
||||||
public class Transform {
|
|
||||||
Dimension size;
|
|
||||||
float rotation;
|
|
||||||
Rectangle region;
|
|
||||||
}
|
|
||||||
|
|
||||||
// eof
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
package org.forkalsrud.album.exif;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileFilter;
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.text.NumberFormat;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.drew.imaging.jpeg.JpegMetadataReader;
|
|
||||||
import com.drew.metadata.Directory;
|
|
||||||
import com.drew.metadata.Metadata;
|
|
||||||
import com.drew.metadata.exif.ExifDirectory;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class DirectoryTest {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDirectoryReader() throws Exception {
|
|
||||||
|
|
||||||
File myDir = new File("photos");
|
|
||||||
assertTrue(myDir.exists());
|
|
||||||
assertTrue(myDir.isDirectory());
|
|
||||||
File[] files = myDir.listFiles(new FileFilter() {
|
|
||||||
|
|
||||||
public boolean accept(File file) {
|
|
||||||
|
|
||||||
return !file.isHidden() && !file.isDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
|
||||||
NumberFormat nf = new DecimalFormat("0");
|
|
||||||
Properties imgProps = new Properties();
|
|
||||||
for (File f : files) {
|
|
||||||
String name = f.getName();
|
|
||||||
String base = "file." + name + ".";
|
|
||||||
|
|
||||||
Metadata metadata = JpegMetadataReader.readMetadata(f);
|
|
||||||
Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);
|
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_ORIENTATION)) {
|
|
||||||
int orientation = exifDirectory.getInt(ExifDirectory.TAG_ORIENTATION);
|
|
||||||
imgProps.setProperty(base + "orientation", nf.format(orientation));
|
|
||||||
}
|
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_WIDTH) &&
|
|
||||||
exifDirectory.containsTag(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT)) {
|
|
||||||
int width = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH);
|
|
||||||
int height = exifDirectory.getInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT);
|
|
||||||
imgProps.setProperty(base + "dimensions", new Dimension(width, height).toString());
|
|
||||||
}
|
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_DATETIME_ORIGINAL)) {
|
|
||||||
Date captureDate = exifDirectory.getDate(ExifDirectory.TAG_DATETIME_ORIGINAL);
|
|
||||||
imgProps.setProperty(base + "captureDate", sdf.format(captureDate));
|
|
||||||
}
|
|
||||||
if (exifDirectory.containsTag(ExifDirectory.TAG_USER_COMMENT)) {
|
|
||||||
String comment = exifDirectory.getString(ExifDirectory.TAG_USER_COMMENT);
|
|
||||||
imgProps.setProperty(base + "comment", comment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imgProps.store(System.out, "Extra Comments");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,226 +0,0 @@
|
||||||
package org.forkalsrud.album.exif;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.awt.Container;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.imageio.ImageReadParam;
|
|
||||||
import javax.imageio.ImageReader;
|
|
||||||
import javax.imageio.metadata.IIOMetadata;
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.w3c.dom.NamedNodeMap;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
|
|
||||||
import com.drew.imaging.jpeg.JpegMetadataReader;
|
|
||||||
import com.drew.imaging.jpeg.JpegProcessingException;
|
|
||||||
import com.drew.metadata.Directory;
|
|
||||||
import com.drew.metadata.Metadata;
|
|
||||||
import com.drew.metadata.MetadataException;
|
|
||||||
import com.drew.metadata.Tag;
|
|
||||||
import com.drew.metadata.exif.ExifDirectory;
|
|
||||||
|
|
||||||
|
|
||||||
public class ExifDataTest {
|
|
||||||
|
|
||||||
String readOrientation(String imgFile) throws IOException {
|
|
||||||
|
|
||||||
ImageInputStream iis = ImageIO.createImageInputStream(new File(imgFile));
|
|
||||||
Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
|
|
||||||
ImageReader reader = readers.next();
|
|
||||||
reader.setInput(iis);
|
|
||||||
IIOMetadata meta = reader.getImageMetadata(0);
|
|
||||||
return displayMetadata(meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOrientation() throws Exception {
|
|
||||||
|
|
||||||
assertEquals("Top, left side (Horizontal / normal)", readOrientation2("photos/IMG_0129.JPG"));
|
|
||||||
assertEquals("Right side, top (Rotate 90 CW)", readOrientation2("photos/IMG_0139.JPG"));
|
|
||||||
|
|
||||||
framePicture("photos/l1000729.jpg");
|
|
||||||
framePicture("photos/l1000802.jpg");
|
|
||||||
// framePicture("photos/IMG_0129.JPG");
|
|
||||||
// framePicture("photos/IMG_0139.JPG");
|
|
||||||
Thread.sleep(50000);
|
|
||||||
}
|
|
||||||
|
|
||||||
String readOrientation2(String imgFile) throws JpegProcessingException, MetadataException {
|
|
||||||
String ret = null;
|
|
||||||
Metadata metadata = JpegMetadataReader.readMetadata(new File(imgFile));
|
|
||||||
// iterate through metadata directories
|
|
||||||
Iterator directories = metadata.getDirectoryIterator();
|
|
||||||
while (directories.hasNext()) {
|
|
||||||
Directory directory = (Directory) directories.next();
|
|
||||||
// iterate through tags and print to System.out
|
|
||||||
Iterator tags = directory.getTagIterator();
|
|
||||||
while (tags.hasNext()) {
|
|
||||||
Tag tag = (Tag) tags.next();
|
|
||||||
// use Tag.toString()
|
|
||||||
System.out.println(tag);
|
|
||||||
if ("Orientation".equals(tag.getTagName())) {
|
|
||||||
ret = String.valueOf(tag.getDescription());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String displayMetadata(IIOMetadata metadata) {
|
|
||||||
|
|
||||||
String ret = null;
|
|
||||||
String [] names = metadata.getMetadataFormatNames();
|
|
||||||
for (int i = 0; i < names.length; ++i) {
|
|
||||||
System.out.println();
|
|
||||||
System.out.println("METADATA FOR FORMAT: " + names[i]);
|
|
||||||
String r1 = displayTree(metadata.getAsTree(names[i]), 0);
|
|
||||||
if (r1 != null) {
|
|
||||||
ret = r1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String displayTree(Node node, int indent) {
|
|
||||||
String ret = null;
|
|
||||||
indent(indent);
|
|
||||||
String name = node.getNodeName();
|
|
||||||
System.out.print("<" + name);
|
|
||||||
NamedNodeMap nm = node.getAttributes();
|
|
||||||
for (int i = 0; i < nm.getLength(); i++) {
|
|
||||||
Node an = nm.item(i);
|
|
||||||
System.out.print(" " + an.getNodeName() + "=\"" + an.getNodeValue() + "\"");
|
|
||||||
if ("ImageOrientation".equals(node.getNodeName()) && "value".equals(an.getNodeName())) {
|
|
||||||
ret = an.getNodeValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (node.hasChildNodes()) {
|
|
||||||
System.out.println(">");
|
|
||||||
NodeList children = node.getChildNodes();
|
|
||||||
for (int i = 0, ub = children.getLength(); i < ub; ++i) {
|
|
||||||
String r1 = displayTree(children.item(i), indent + 4);
|
|
||||||
if (r1 != null) {
|
|
||||||
ret = r1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
indent(indent);
|
|
||||||
System.out.println("</" + name + ">");
|
|
||||||
} else {
|
|
||||||
System.out.println("/>");
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void indent(int indent) {
|
|
||||||
for (int i = 0; i < indent; ++i)
|
|
||||||
System.out.print(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testThumbnail() throws Exception {
|
|
||||||
|
|
||||||
assertEquals(1, getOrientationID("photos/IMG_0129.JPG"));
|
|
||||||
assertEquals(6, getOrientationID("photos/IMG_0139.JPG"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// case 1: return "Top, left side (Horizontal / normal)";
|
|
||||||
// case 2: return "Top, right side (Mirror horizontal)";
|
|
||||||
// case 3: return "Bottom, right side (Rotate 180)";
|
|
||||||
// case 4: return "Bottom, left side (Mirror vertical)";
|
|
||||||
// case 5: return "Left side, top (Mirror horizontal and rotate 270 CW)";
|
|
||||||
// case 6: return "Right side, top (Rotate 90 CW)";
|
|
||||||
// case 7: return "Right side, bottom (Mirror horizontal and rotate 90 CW)";
|
|
||||||
// case 8: return "Left side, bottom (Rotate 270 CW)";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param imgFile
|
|
||||||
* @return
|
|
||||||
* @throws JpegProcessingException
|
|
||||||
* @throws MetadataException
|
|
||||||
*/
|
|
||||||
int getOrientationID(String imgFile) throws JpegProcessingException, MetadataException {
|
|
||||||
Metadata metadata = JpegMetadataReader.readMetadata(new File(imgFile));
|
|
||||||
Directory exifDirectory = metadata.getDirectory(ExifDirectory.class);
|
|
||||||
int orientation = exifDirectory.getInt(ExifDirectory.TAG_ORIENTATION);
|
|
||||||
return orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void framePicture(String imgFile) throws Exception {
|
|
||||||
|
|
||||||
JFrame frame = new JFrame(imgFile);
|
|
||||||
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
|
||||||
|
|
||||||
Container c = frame.getContentPane();
|
|
||||||
c.add(new ImgComponent(imgFile));
|
|
||||||
frame.pack();
|
|
||||||
frame.setVisible(true);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ImgComponent extends JComponent {
|
|
||||||
|
|
||||||
BufferedImage img;
|
|
||||||
|
|
||||||
public ImgComponent(String imgFile) throws IOException, JpegProcessingException, MetadataException {
|
|
||||||
Iterator readers = ImageIO.getImageReadersByFormatName("jpg");
|
|
||||||
ImageReader reader = (ImageReader)readers.next();
|
|
||||||
ImageInputStream iis = ImageIO.createImageInputStream(new File(imgFile));
|
|
||||||
reader.setInput(iis, true);
|
|
||||||
ImageReadParam param = reader.getDefaultReadParam();
|
|
||||||
param.setSourceSubsampling(8, 8, 0, 0);
|
|
||||||
img = reader.read(0, param);
|
|
||||||
|
|
||||||
if (getOrientationID(imgFile) == 6) {
|
|
||||||
BufferedImage buf2 = new BufferedImage(img.getHeight(), img.getWidth(), img.getType());
|
|
||||||
Graphics2D g2 = buf2.createGraphics();
|
|
||||||
g2.translate(img.getHeight() / 2, img.getWidth() / 2);
|
|
||||||
g2.rotate(Math.PI / 2);
|
|
||||||
g2.translate(-img.getWidth() / 2, -img.getHeight() / 2);
|
|
||||||
g2.drawImage(img, 0, 0, this);
|
|
||||||
img = buf2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension getPreferredSize() {
|
|
||||||
return new Dimension(img.getWidth(this), img.getHeight(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
|
|
||||||
super.paintComponent(g);
|
|
||||||
g.drawImage(img, 0, 0, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -55,34 +55,19 @@ public class AlbumServlet
|
||||||
res.sendError(HttpServletResponse.SC_NOT_FOUND);
|
res.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String page = null;
|
|
||||||
if (pathInfo == null || "/".equals(pathInfo)) {
|
if (pathInfo.endsWith(".album")) {
|
||||||
page = "album";
|
|
||||||
} else if (pathInfo.endsWith(".album")) {
|
|
||||||
pathInfo = pathInfo.substring(0, pathInfo.length() - ".album".length());
|
pathInfo = pathInfo.substring(0, pathInfo.length() - ".album".length());
|
||||||
page = "album";
|
handleAlbum(req, res, (DirectoryEntry)resolveEntry(pathInfo));
|
||||||
}
|
|
||||||
if (page != null) {
|
|
||||||
DirectoryEntry entry = null;
|
|
||||||
entry = (DirectoryEntry)resolveEntry(pathInfo);
|
|
||||||
handleAlbum(req, res, entry);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathInfo.endsWith(".photo")) {
|
if (pathInfo.endsWith(".photo")) {
|
||||||
pathInfo = pathInfo.substring(0, pathInfo.length() - ".photo".length());
|
pathInfo = pathInfo.substring(0, pathInfo.length() - ".photo".length());
|
||||||
page = "photo";
|
|
||||||
handlePhoto(req, res, (FileEntry)resolveEntry(pathInfo));
|
handlePhoto(req, res, (FileEntry)resolveEntry(pathInfo));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
int parentPos = pathInfo.substring(0, pathInfo.length() - 1).lastIndexOf('/');
|
|
||||||
if (parentPos >= 0) {
|
|
||||||
req.setAttribute("parent", req.getServletPath() + pathInfo.substring(0, parentPos) + "/");
|
|
||||||
}
|
|
||||||
req.setAttribute("assets", "/" + req.getContextPath() + "assets");
|
|
||||||
*/
|
|
||||||
File file = new File(base, pathInfo);
|
File file = new File(base, pathInfo);
|
||||||
if (!file.canRead()) {
|
if (!file.canRead()) {
|
||||||
res.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
res.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
/*
|
|
||||||
$Id: pxapplication.css,v 1.1 2008/03/17 01:01:36 knut Exp $
|
|
||||||
|
|
||||||
Pixory - the personal image server
|
|
||||||
Copyright 2004-2005 Joe Panico
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License, version 2, as
|
|
||||||
published by the Free Software Foundation.
|
|
||||||
|
|
||||||
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, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* predefined elements */
|
|
||||||
html { height: 100%; text-align:center; font-family: verdana, arial, helvetica, sans-serif; }
|
|
||||||
|
|
||||||
body { height: 100%; margin: 0px; padding: 1px; }
|
|
||||||
|
|
||||||
hr { width: 100%; height: 1px; border: none; background-color:#7070a1; }
|
|
||||||
|
|
||||||
/* pseudo classes */
|
|
||||||
a:link {color:#606091;}
|
|
||||||
a:visited {color:#606091;}
|
|
||||||
|
|
||||||
/* force vertical scrollbar in Moz */
|
|
||||||
#force-scrollbar { position: absolute; top: 0; bottom: -1px; width: 1em; z-index: -1; }
|
|
||||||
|
|
||||||
/* generic classes */
|
|
||||||
/* i.e. css side orderings: top, right, bottom, left */
|
|
||||||
|
|
||||||
.thintable { width: 100%; border: none; border-collapse: collapse; padding: 0px; }
|
|
||||||
.error_message { font-size: medium; font-style: italic; }
|
|
||||||
/* a piece of text styled to look like a button */
|
|
||||||
.text_button { border: 1px solid black; color: black; background-color: rgb(80%,80%,80%); text-align: center; padding: 3px 5px 3px 5px; text-decoration: none;}
|
|
||||||
|
|
||||||
/* currently used only on ViewerHome */
|
|
||||||
.dropShadowContent { float: left; position: relative; left: -2px; top: -2px; border: none; background: #9fc;}
|
|
||||||
.dropShadowContainer { float: left; position: relative; background: #666; margin: 4px; border: none;}
|
|
||||||
|
|
||||||
/* PXShowMessage */
|
|
||||||
.show_message_table { border: none; height: 35px;}
|
|
||||||
.show_message_table .success_message_cell { color: black;}
|
|
||||||
.show_message_table .running_message_cell { color: black;}
|
|
||||||
.show_message_table .error_message_cell { color: red;}
|
|
||||||
.show_message_table .warn_message_cell { color: red;}
|
|
||||||
|
|
||||||
/* PXPageDecorator */
|
|
||||||
#page_decorator_table { height: 100%; width: 100%; border: none; color:#606091; background-color: #fffffb; vertical-align: top; text-align: left; margin: 0px; padding: 0px;}
|
|
||||||
#page_decorator_cell { height: 90%; border:none; vertical-align: top;}
|
|
||||||
#footer_cell { border: none; text-align: right; vertical-align: bottom; font-size: small; font-style: italic; color: #666; padding: 0px 4px 4px 0px; }
|
|
||||||
|
|
||||||
/* Message page */
|
|
||||||
#message_table {width: 30%; height: 30%; vertical-align: middle; text-align: center; margin-left: auto; margin-right:auto; border: 1px solid orange; background-color: #ddd;}
|
|
||||||
#message_table td { padding: 10px; }
|
|
||||||
|
|
||||||
/* all pages */
|
|
||||||
#content_table { width: 100%; border: none; text-align: center; border-collapse: collapse; }
|
|
||||||
|
|
||||||
/* pxtapestry:PXPropertiesTable */
|
|
||||||
table.properties_table { border: 1px dotted #ccc; text-align: left; font-size: xx-small; margin: 0px 7px 0px 7px; }
|
|
||||||
table.properties_table caption { font-size: small; font-weight: bold; text-decoration: underline; text-align: center; }
|
|
||||||
table.properties_table tr.even { background-color: #ccb; }
|
|
||||||
table.properties_table td { padding: 0px 5px 0px 5px; }
|
|
||||||
|
|
||||||
/* all/any viewer pages */
|
|
||||||
.image { border: 1px solid #606091; padding: 0px;}
|
|
||||||
.caption { border: none; font-size: xx-small; padding: 0px; vertical-align: top;}
|
|
||||||
.filename { border: none; font-size: xx-small; font-style: italic; padding: 0px; vertical-align: top;}
|
|
||||||
.photo_grid_table { width: 100%; height: 100%; vertical-align: top; padding: 0px 0px 0px 0px; border: none; border-spacing: 7px; empty-cells: hide; background-color: #ddd; }
|
|
||||||
.photo_grid_cell { vertical-align: top; background-color: #fffffb; border: 1px dotted #ccc; padding: 0px 0px 0px 0px; }
|
|
||||||
|
|
||||||
/* ViewerHome */
|
|
||||||
#viewer_home_title_cell {border: none; text-align: left; font-size: x-large; padding: 10px 20px 10px 10px; }
|
|
||||||
#viewer_home_greeting_cell {border: none; text-align: right; font-size: xx-small; padding: 5px 20px 5px 0px; }
|
|
||||||
#viewer_home_noalbums_cell {border: none; text-align: center; padding: 60px 0px 30px 0px; }
|
|
||||||
|
|
||||||
td.home_year { text-align: left; font-size: large; font-weight: bold; padding: 5px 5px 5px 5px; }
|
|
||||||
table.home_entry_table { width: 100%; vertical-align: top; text-align: center; font-size: xx-small; color:#606091; }
|
|
||||||
table.home_entry_table td.caption { padding: 0px 5px 5px 5px; }
|
|
||||||
|
|
||||||
/* album/index pages */
|
|
||||||
#album_header_table { border: none; width: 100%; padding: 0px; vertical-align: top; border-collapse: collapse; }
|
|
||||||
#album_name_cell { width: 50%; text-align: left; font-weight: bold; }
|
|
||||||
#album_control_cell { width: 50%; text-align: left; font-weight: bold; }
|
|
||||||
#album_control_cell .button { width: 15% }
|
|
||||||
#album_control_cell .control { width: 35%; text-align: right; }
|
|
||||||
#album_control_cell .label { width: 35%; text-align: center; font-size: small; color: #888; }
|
|
||||||
|
|
||||||
/* album pages */
|
|
||||||
.album_image_table { border: none; border-collapse: collapse; margin-left: auto; margin-right:auto; }
|
|
||||||
.album_image_table td { padding: 0px; }
|
|
||||||
.album_image_table .image_properties { height: 16px; font-size: xx-small; color: #888; }
|
|
||||||
.album_narrative_cell { padding: 0px 10px 20px 10px; white-space: normal; border: none; }
|
|
||||||
|
|
||||||
/* index page */
|
|
||||||
table.index_entry_table { border: none; height: 100%; width: 100%; vertical-align: middle; text-align: center; font-size: xx-small; color:#606091; }
|
|
||||||
|
|
||||||
/* FullPhoto page */
|
|
||||||
table.full_photo { border: none; width: 100%; height: 100%; vertical-align: middle; text-align: center; border-collapse: collapse; padding: 0px; margin-left: auto; margin-right:auto;}
|
|
||||||
|
|
||||||
/* AboutPanel */
|
|
||||||
#about_table { border: 1px dotted #ccc; text-align: left; font-size: small; margin: 0px 7px 0px 0px; }
|
|
||||||
#about_table .heading { text-align: center; padding: 7px; }
|
|
||||||
#about_table .properties_table { text-align: left; border-top: 1px solid #ccc;}
|
|
||||||
#about_table .author { font-weight: bold; }
|
|
||||||
#about_table .label { width: 20%; text-align: right; }
|
|
||||||
#about_table .odd { background-color: #ccb; }
|
|
||||||
#about_table .centered { text-align: center; }
|
|
||||||
|
|
||||||
/* AlbumDownload */
|
|
||||||
#download_table { border: 1px dotted #ccc; text-align: center; font-size: small; margin: 0px 7px 0px 7px; }
|
|
||||||
|
|
||||||
/* Login, SendCredentials */
|
|
||||||
.icon_table { width: 100%; border: none; text-align: right; }
|
|
||||||
.centering_table { width: 100%; height: 100%; vertical-align: middle; text-align: center; border: none; }
|
|
||||||
|
|
||||||
#login_table { border: 2px solid orange; background-color: #ddd; margin-left: auto; margin-right:auto; text-align: left; empty-cells: show;}
|
|
||||||
#login_table .error { height: 35px; }
|
|
||||||
#login_table .label { text-align: right; }
|
|
||||||
#login_table .submit { text-align: right; }
|
|
||||||
|
|
||||||
.submit_button { padding: 0px ; border: 1px solid black; background-color: orange; }
|
|
||||||
|
|
||||||
.form_field { padding: 0px 0px 0px 5px; border: 1px solid #888; }
|
|
||||||
|
|
||||||
Loading…
Add table
Reference in a new issue