Skip to content

Instantly share code, notes, and snippets.

@apb2006
Created May 16, 2013 16:59
Show Gist options
  • Save apb2006/5593268 to your computer and use it in GitHub Desktop.
Save apb2006/5593268 to your computer and use it in GitHub Desktop.
baseX 7.7 passing java objects with function reference. Requires "metadata-extractor-2.6.4.jar" "xmpcore.jar" from http://drewnoakes.com/code/exif/
xquery version "3.0" encoding "UTF-8";
(:~ return image metadata as xml using http://drewnoakes.com/code/exif/
: usage: metadata:read('C:/temp/apic.jpg')
: xml format based on xmlcalabash1
: https://github.com/ndw/xmlcalabash1/blob/master/src/com/xmlcalabash/extensions/MetadataExtractor.java
: @author andy bunce
:)
module namespace metadata = 'apb.image.metadata';
declare default function namespace 'apb.image.metadata';
declare namespace File="java:java.io.File";
declare namespace URL="java:java.net.URL";
declare namespace URLConnection="java.net.URLConnection";
declare namespace Tag="java:com.drew.metadata.Tag";
declare namespace ImageMetadataReader="java:com.drew.imaging.ImageMetadataReader";
declare namespace Metadata="java:com.drew.metadata.Metadata";
declare namespace Directory="java:com.drew.metadata.Directory";
declare namespace ArrayList="java:java.util.ArrayList";
(:~ extract metadata
: @param path
: @param ignore tag names to ignore
:)
declare function read($path as xs:string) as element(metadata)
{
<metadata>{tags($path)}</metadata>
};
declare function tags($path as xs:string) as element(tag)*
{
try {
let $src := src($path)
let $meta:=ImageMetadataReader:readMetadata($src)
let $dirs:=Metadata:getDirectories($meta)
return java-for-each($dirs,dir#1)
} catch * {
<tag error="{$err:description}"/>
}
};
(:~ tags in directory :)
declare function dir($dir) as element(tag)*
{
let $tags:= Directory:getTags($dir)
return java-for-each($tags,tag#1)
};
(:~ extract a single tag :)
declare function tag($tag) as element(tag)
{
let $name:=Tag:getTagName($tag),
$value:=Tag:getDescription($tag),
$dir:=Tag:getDirectoryName($tag),
$type:=Tag:getTagTypeHex($tag)
(: let $value:=isodate($value) :)
return <tag name="{$name}" dir="{$dir}" type="{$type}">{$value}</tag>
};
(:~ file or stream for http
: http NOT WORKING
:)
declare function src($path){
if(fn:starts-with($path,"http:/"))
then
let $url:=URL:new($path)
let $url:=fn:trace($url,"}}}}}")
return URL:openStream($url)
else File:new($path)
};
(:~ apply function fn to each item in java list thing :)
declare function java-for-each($items,$fn)
{
for $i in 0 to ArrayList:size($items) -1
let $s:= ArrayList:get($items,xs:int($i))
return $fn($s)
};
xquery version "3.0" encoding "UTF-8";
(:~ return image metadata as xml using http://drewnoakes.com/code/exif/
: usage: metadata:read('C:/temp/apic.jpg')
: xml format based on xmlcalabash1
: https://github.com/ndw/xmlcalabash1/blob/master/src/com/xmlcalabash/extensions/MetadataExtractor.java
: @author andy bunce
:)
module namespace metadata = 'apb.image.metadata';
declare default function namespace 'apb.image.metadata';
declare namespace File="java:java.io.File";
declare namespace URL="java:java.net.URL";
declare namespace URLConnection="java.net.URLConnection";
declare namespace Tag="java:com.drew.metadata.Tag";
declare namespace ImageMetadataReader="java:com.drew.imaging.ImageMetadataReader";
declare namespace Metadata="java:com.drew.metadata.Metadata";
declare namespace Directory="java:com.drew.metadata.Directory";
declare namespace ArrayList="java:java.util.ArrayList";
(:~ extract metadata
: @param path
: @param ignore tag names to ignore
:)
declare function read($path as xs:string) as element(metadata)
{
<metadata>{tags($path)}</metadata>
};
declare function tags($path as xs:string) as element(tag)*
{
try {
let $src := src($path)
let $meta:=ImageMetadataReader:readMetadata($src)
let $dirs:=Metadata:getDirectories($meta)
return dir-for-each($dirs,dir#1)
} catch * {
<tag error="{$err:description}"/>
}
};
(:~ tags in directory :)
declare function dir($dir) as element(tag)*
{
let $tags:= Directory:getTags($dir)
return tag-for-each($tags,tag#1)
};
(:~ extract a single tag :)
declare function tag($tag) as element(tag)
{
let $name:=Tag:getTagName($tag),
$value:=Tag:getDescription($tag),
$dir:=Tag:getDirectoryName($tag),
$type:=Tag:getTagTypeHex($tag)
(: let $value:=isodate($value) :)
return <tag name="{$name}" dir="{$dir}" type="{$type}">{$value}</tag>
};
(:~ file or stream for http
: http NOT WORKING
:)
declare function src($path){
if(fn:starts-with($path,"http:/"))
then
let $url:=URL:new($path)
let $url:=fn:trace($url,"}}}}}")
return URL:openStream($url)
else File:new($path)
};
(:~ apply function fn to each item in java list thing :)
declare function tag-for-each($items,$fn)
{
for $i in 0 to ArrayList:size($items) -1
let $s:= ArrayList:get($items,xs:int($i))
return tag($s)
};
(:~ apply function fn to each item in java list thing :)
declare function dir-for-each($items,$fn)
{
for $i in 0 to ArrayList:size($items) -1
let $s:= ArrayList:get($items,xs:int($i))
return dir($s)
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment