/
library-uowfile.html
210 lines (159 loc) · 14 KB
/
library-uowfile.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>UoWFile</title><link rel="stylesheet" href="css/style.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /><link rel="home" href="index.html" title="" /><link rel="up" href="libraries.html" title="Libraries" /><link rel="prev" href="library-uid.html" title="UID" /><link rel="next" href="extensions.html" title="Extensions" />
<!-- favicon -->
<link rel="shortcut icon" href="http://qi4j.org/favicon.ico" type="image/vnd.microsoft.icon" />
<link rel="icon" href="http://qi4j.org/favicon.ico" type="image/x-icon" />
<!-- style -->
<link href="css/shCore.css" rel="stylesheet" type="text/css" />
<link href="css/shCoreEclipse.css" rel="stylesheet" type="text/css" />
<link href="css/shThemeEclipse.css" rel="stylesheet" type="text/css" />
<link href="css/qi4j.css" rel="stylesheet" type="text/css" />
<!-- Syntax Highlighter -->
<script type="text/javascript" src="js/shCore.js"></script>
<script type="text/javascript" src="js/shBrushJava.js"></script>
<script type="text/javascript" src="js/shBrushScala.js"></script>
<script type="text/javascript" src="js/shBrushJScript.js"></script>
<script type="text/javascript" src="js/shBrushBash.js"></script>
<script type="text/javascript" src="js/shBrushPlain.js"></script>
<script type="text/javascript" src="js/shBrushXml.js"></script>
<script type="text/javascript" src="js/shBrushGroovy.js"></script>
<script type="text/javascript" src="js/shBrushPython.js"></script>
<script type="text/javascript" src="js/shBrushRuby.js"></script>
<script type="text/javascript" src="js/shBrushCSharp.js"></script>
<script type="text/javascript">
SyntaxHighlighter.defaults['tab-size'] = 4;
SyntaxHighlighter.defaults['gutter'] = false;
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all()
</script>
<!-- JQuery -->
<script type="text/javascript" src="js/jquery-1.6.4.min.js"></script>
<!-- Image Scaler -->
<script type="text/javascript" src="js/imagescaler.js"></script>
<!-- Table Styler -->
<script type="text/javascript" src="js/tablestyler.js"></script>
<!-- Qi4j WebSite Progressive Enhancement -->
<link href="css/progressive-enhancement.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/jquery.scrollTo-1.4.2.js"></script>
<script type="text/javascript" src="js/progressive-enhancement.js"></script>
<!-- Analytics -->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-3118496-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head><body><div xmlns="" xmlns:exsl="http://exslt.org/common" class="logo"><a href="index.html"><img src="images/logo-standard.png" /></a></div><div xmlns="" xmlns:exsl="http://exslt.org/common" class="top-nav"><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><dl><dt><span class="section"><a href="index.html#home">Qi4j</a></span></dt><dt><span class="section"><a href="intro.html">Introduction</a></span></dt><dt><span class="section"><a href="tutorials.html">Tutorials</a></span></dt><dt><span class="section"><a href="javadocs.html">Javadoc</a></span></dt><dt><span class="section"><a href="samples.html">Samples</a></span></dt><dt><span class="section"><a href="core.html">Core</a></span></dt><dt><span class="section"><span xmlns="" href="libraries.html">Libraries</span></span></dt><dt><span class="section"><a href="extensions.html">Extensions</a></span></dt><dt><span class="section"><a href="tools.html">Tools</a></span></dt><dt><span class="section"><a href="glossary.html">Glossary </a></span></dt></dl></div></div><div xmlns="" xmlns:exsl="http://exslt.org/common" class="sub-nav"><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><dl><dt><span class="section"><a href="libraries.html#_overview_5">Overview</a></span></dt><dt><span class="section"><a href="library-alarm.html">Alarms</a></span></dt><dt><span class="section"><a href="library-caching.html">Caching</a></span></dt><dt><span class="section"><a href="library-circuitbreaker.html">Circuit Breaker</a></span></dt><dt><span class="section"><a href="library-constraints.html">Constraints</a></span></dt><dt><span class="section"><a href="library-conversion.html">Conversion</a></span></dt><dt><span class="section"><a href="library-cxf.html">CXF WebService</a></span></dt><dt><span class="section"><a href="library-eventsourcing.html">Event Sourcing</a></span></dt><dt><span class="section"><a href="library-eventsourcing-jdbm.html">Event Sourcing - JDBM</a></span></dt><dt><span class="section"><a href="library-eventsourcing-rest.html">Event Sourcing - ReST</a></span></dt><dt><span class="section"><a href="library-fileconfig.html">FileConfig</a></span></dt><dt><span class="section"><a href="library-http.html">HTTP</a></span></dt><dt><span class="section"><a href="library-jmx.html">JMX</a></span></dt><dt><span class="section"><a href="library-locking.html">Locking</a></span></dt><dt><span class="section"><a href="library-logging.html">Logging</a></span></dt><dt><span class="section"><a href="library-neo4j.html">Neo4j</a></span></dt><dt><span class="section"><a href="library-osgi.html">OSGi</a></span></dt><dt><span class="section"><a href="library-rdf.html">RDF</a></span></dt><dt><span class="section"><a href="library-rest-client.html">ReST Client</a></span></dt><dt><span class="section"><a href="library-rest-client-primer.html">ReST - HATEOAS Primer</a></span></dt><dt><span class="section"><a href="library-rest-common.html">ReST Common</a></span></dt><dt><span class="section"><a href="library-rest-server.html">ReST Server</a></span></dt><dt><span class="section"><a href="library-scheduler.html">Scheduler</a></span></dt><dt><span class="section"><a href="library-script-beanshell.html">Beanshell Scripting</a></span></dt><dt><span class="section"><a href="library-script-groovy.html">Groovy Scripting</a></span></dt><dt><span class="section"><a href="library-script-javascript.html">Javascript Scripting</a></span></dt><dt><span class="section"><a href="library-script-jruby.html">JRuby Scripting</a></span></dt><dt><span class="section"><a href="lang-scala.html">Scala Support</a></span></dt><dt><span class="section"><a href="library-servlet.html">Servlet</a></span></dt><dt><span class="section"><a href="library-shiro.html">Shiro Security</a></span></dt><dt><span class="section"><a href="library-shiro-web.html">Shiro Web Security</a></span></dt><dt><span class="section"><a href="library-spring.html">Spring Integration</a></span></dt><dt><span class="section"><a href="library-sql.html">SQL</a></span></dt><dt><span class="section"><a href="library-struts-codebehind.html">Struts - Code Behind</a></span></dt><dt><span class="section"><a href="library-struts-convention.html">Struts - Convention</a></span></dt><dt><span class="section"><a href="library-struts-plugin.html">Struts - Plugin</a></span></dt><dt><span class="section"><a href="library-uid.html">UID</a></span></dt><dt><span class="section"><span xmlns="" href="library-uowfile.html">UoWFile</span></span></dt></dl></div></div><div class="section" title="UoWFile"><div class="titlepage"><div><div><h3 class="title"><a id="library-uowfile"></a>UoWFile</h3></div></div></div><p class="remark"><i><span class="comment"></span></i></p><p class="devstatus-code-stable">code</p><p class="devstatus-docs-good">docs</p><p class="devstatus-tests-complete">tests</p><p>The UoWFile Library provides an easy way to bind file operations to UnitOfWorks.</p><p>In other words, using this library you can easily attach files to your
Composites, mostly EntityComposites, so that if the UoW gets discarded, changes
to files are discarded too. Concurrent modifications are properly handled.</p><p>Note that it has a performance impact relative to the files size as it
duplicates the file to keep a backup for eventual rollback. However, the API
provides a way to get non-managed handles on the attached files to keep your
read-only operations fast.</p><p>The location of files is left to the developer using a private mixin.</p><div class="table"><a id="idp20596728"></a><p class="title"><b>Table 61. Artifact</b></p><div class="table-contents"><table summary="Artifact" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th align="left" valign="top">Group ID</th><th align="left" valign="top">Artifact ID</th><th align="left" valign="top">Version</th></tr></thead><tbody><tr><td align="left" valign="top"><p>org.qi4j.library</p></td><td align="left" valign="top"><p>org.qi4j.library.uowfile</p></td><td align="left" valign="top"><p>2.0</p></td></tr></tbody></table></div></div><br class="table-break" /><div class="section" title="Logging"><div class="titlepage"><div><div><h4 class="title"><a id="_logging_6"></a>Logging</h4></div></div></div><p>The SLF4J Logger used by this library is named "org.qi4j.library.uowfile".</p></div><div class="section" title="Add an attached file to an Entity"><div class="titlepage"><div><div><h4 class="title"><a id="_add_an_attached_file_to_an_entity"></a>Add an attached file to an Entity</h4></div></div></div><p>Let’s say you have the following Entity:</p><pre class="programlisting brush: java">public interface TestedEntity
extends EntityComposite,
[...snip...]
{
Property<String> name();
}
</pre><p>To add an attached file to it you first need to extends HasUoWFileLifecycle:</p><pre class="programlisting brush: java">public interface TestedEntity
extends EntityComposite,
HasUoWFileLifecycle
{
Property<String> name();
}
</pre><p>This provides you with the following contract:</p><pre class="programlisting brush: java">public interface HasUoWFile
{
/**
* IMPORTANT Use this {@link File} only inside read-only {@link UnitOfWork}s
*/
File attachedFile();
File managedFile();
[...snip...]
}
</pre><p>Next you need to write the UoWFileLocator mixin:</p><pre class="programlisting brush: java">public static abstract class TestedFileLocatorMixin
implements UoWFileLocator
{
@This
private Identity meAsIdentity;
@Override
public File locateAttachedFile()
{
return new File( baseTestDir, meAsIdentity.identity().get() );
}
}
</pre><p>Assemble all this as follow:</p><pre class="programlisting brush: java">public void assemble( ModuleAssembly module )
throws AssemblyException
{
new UoWFileAssembler().assemble( module );
module.entities( TestedEntity.class ).withMixins( TestedFileLocatorMixin.class );
[...snip...]
}
</pre><p>You can now use the following methods on your EntityComposite:</p><pre class="programlisting brush: java">File attachedFile = entity.attachedFile();
File managedFile = entity.managedFile();
</pre></div><div class="section" title="Going plural"><div class="titlepage"><div><div><h4 class="title"><a id="_going_plural"></a>Going plural</h4></div></div></div><p>Now if you want to attach several files to one entity, this library provides a
simple mechanism allowing you to use any enum as discriminator.</p><p>Let’s say you have the following Entity:</p><pre class="programlisting brush: java">public interface TestedEntity
extends EntityComposite,
[...snip...]
{
Property<String> name();
}
</pre><p>It’s the very same as the one used to start the singular file support described
above.</p><p>To add an attached file to it you first need to write an enum and extends
HasUoWFilesLifecycle:</p><pre class="programlisting brush: java">public enum MyEnum
{
fileOne, fileTwo
}
public interface TestedEntity
extends EntityComposite,
HasUoWFilesLifecycle<MyEnum>
{
Property<String> name();
}
</pre><p>This provides you with the following contract:</p><pre class="programlisting brush: java">public interface HasUoWFiles<T extends Enum<T>>
{
/**
* IMPORTANT Use this {@link File} only inside read-only {@link UnitOfWork}s
*/
File attachedFile( T key );
/**
* IMPORTANT Use these {@link File}s only inside read-only {@link UnitOfWork}s
*/
Iterable<File> attachedFiles();
File managedFile( T key );
Iterable<File> managedFiles();
[...snip...]
}
</pre><p>Next you need to write the UoWFileLocator mixin:</p><pre class="programlisting brush: java">public static abstract class TestedFilesLocatorMixin
implements UoWFilesLocator<MyEnum>
{
@This
private Identity meAsIdentity;
@Override
public Iterable<File> locateAttachedFiles()
{
List<File> list = new ArrayList<File>();
for ( MyEnum eachValue : MyEnum.values() ) {
list.add( new File( baseTestDir, meAsIdentity.identity().get() + "." + eachValue.name() ) );
}
return list;
}
@Override
public File locateAttachedFile( MyEnum key )
{
return new File( baseTestDir, meAsIdentity.identity().get() + "." + key.name() );
}
}
</pre><p>Assemble all this as follow:</p><pre class="programlisting brush: java">public void assemble( ModuleAssembly module )
throws AssemblyException
{
new UoWFileAssembler().assemble( module );
module.entities( TestedEntity.class ).withMixins( TestedFilesLocatorMixin.class );
[...snip...]
}
</pre><p>You can now use the following methods on your EntityComposite:</p><pre class="programlisting brush: java">File attachedFileTwo = entity.attachedFile( MyEnum.fileTwo );
File managedFileOne = entity.managedFile( MyEnum.fileOne );
</pre></div></div><div xmlns="" xmlns:exsl="http://exslt.org/common" class="footer">(c) 2012 The Qi4j Community</div></body></html>