├── .gitignore
├── README.md
├── aa
├── db-diagram.png
├── examples
└── mc-vfs-gettingstarted
│ ├── nbactions.xml
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ └── com
│ │ └── gettingstarted
│ │ └── web
│ │ └── VfsController.java
│ ├── resources
│ ├── database.xml
│ ├── default.properties
│ ├── ehcache.xml
│ ├── log4j.properties
│ ├── milton.license.properties
│ ├── milton.license.sig
│ ├── miltonContext.xml
│ └── rootContext.xml
│ └── webapp
│ ├── WEB-INF
│ └── web.xml
│ └── templates
│ └── directory.jsp
├── milton-cloud-sync-app
├── application
│ ├── nb-configuration.xml
│ ├── pom.xml
│ ├── src
│ │ └── test
│ │ │ └── java
│ │ │ └── io
│ │ │ └── milton
│ │ │ └── ApplicationTest.java
│ └── ~
│ │ └── syncdb.h2.db
├── branding
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ ├── nbm-branding
│ │ ├── core
│ │ │ └── core.jar
│ │ │ │ └── org
│ │ │ │ └── netbeans
│ │ │ │ └── core
│ │ │ │ └── startup
│ │ │ │ ├── Bundle.properties
│ │ │ │ ├── frame.gif
│ │ │ │ ├── frame32.gif
│ │ │ │ ├── frame48.gif
│ │ │ │ └── splash.gif
│ │ └── modules
│ │ │ ├── org-netbeans-core-windows.jar
│ │ │ └── org
│ │ │ │ └── netbeans
│ │ │ │ └── core
│ │ │ │ └── windows
│ │ │ │ ├── Bundle.properties
│ │ │ │ └── view
│ │ │ │ └── ui
│ │ │ │ └── Bundle.properties
│ │ │ └── org-netbeans-core.jar
│ │ │ └── org
│ │ │ └── netbeans
│ │ │ └── core
│ │ │ └── ui
│ │ │ └── Bundle.properties
│ │ ├── nbm
│ │ └── manifest.mf
│ │ └── resources
│ │ └── io
│ │ └── milton
│ │ └── branding
│ │ └── Bundle.properties
├── milton-cloud-tool
│ ├── pom.xml
│ ├── src
│ │ └── main
│ │ │ ├── java
│ │ │ └── guiTool
│ │ │ │ ├── Helper.java
│ │ │ │ ├── SyncToolTopComponent.form
│ │ │ │ ├── SyncToolTopComponent.java
│ │ │ │ ├── addJob.form
│ │ │ │ ├── addJob.java
│ │ │ │ ├── base.java
│ │ │ │ ├── updateJob.form
│ │ │ │ └── updateJob.java
│ │ │ ├── nbm
│ │ │ └── manifest.mf
│ │ │ └── resources
│ │ │ ├── Bundle.properties
│ │ │ └── images
│ │ │ ├── logo-dark.png
│ │ │ └── upload.png
│ └── ~
│ │ ├── syncdb.h2.db
│ │ └── syncdb.trace.db
└── pom.xml
├── milton-cloud-sync
├── Key
├── nbactions.xml
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ ├── com
│ │ │ │ ├── bradmcevoy
│ │ │ │ │ ├── io
│ │ │ │ │ │ ├── Base64Coder.java
│ │ │ │ │ │ ├── ChunkStore.java
│ │ │ │ │ │ ├── ChunkWriter.java
│ │ │ │ │ │ ├── ChunkingInputStream.java
│ │ │ │ │ │ ├── ChunkingOutputStream.java
│ │ │ │ │ │ ├── ReadingException.java
│ │ │ │ │ │ ├── StreamToStream.java
│ │ │ │ │ │ └── WritingException.java
│ │ │ │ │ ├── utils
│ │ │ │ │ │ ├── DateUtils.java
│ │ │ │ │ │ ├── ElementList.java
│ │ │ │ │ │ ├── FileUtils.java
│ │ │ │ │ │ ├── IntegerUtils.java
│ │ │ │ │ │ ├── StreamReader.java
│ │ │ │ │ │ ├── StreamWriter.java
│ │ │ │ │ │ ├── StringUtils.java
│ │ │ │ │ │ ├── TypeUtils.java
│ │ │ │ │ │ ├── With.java
│ │ │ │ │ │ └── entities.properties
│ │ │ │ │ └── version
│ │ │ │ │ │ ├── Block.java
│ │ │ │ │ │ ├── BlockStore.java
│ │ │ │ │ │ └── VersioningOutputStream.java
│ │ │ │ └── ettrema
│ │ │ │ │ ├── common
│ │ │ │ │ ├── Service.java
│ │ │ │ │ └── Withee.java
│ │ │ │ │ ├── config
│ │ │ │ │ ├── CatalogConfigurator.java
│ │ │ │ │ └── ConfigurationException.java
│ │ │ │ │ ├── context
│ │ │ │ │ ├── Accessor.java
│ │ │ │ │ ├── BeanFactory.java
│ │ │ │ │ ├── BeanLocator.java
│ │ │ │ │ ├── BeanWrapper.java
│ │ │ │ │ ├── ClassBeanLocator.java
│ │ │ │ │ ├── ClassNotInContextException.java
│ │ │ │ │ ├── Context.java
│ │ │ │ │ ├── Contextual.java
│ │ │ │ │ ├── CtxJdbcConnectionFactory.java
│ │ │ │ │ ├── CtxRootFolderFactory.java
│ │ │ │ │ ├── Dependent.java
│ │ │ │ │ ├── Executable.java
│ │ │ │ │ ├── Executable2.java
│ │ │ │ │ ├── Factory.java
│ │ │ │ │ ├── FactoryCatalog.java
│ │ │ │ │ ├── ListFactory.java
│ │ │ │ │ ├── PostgresUtils.java
│ │ │ │ │ ├── ReferenceBeanLocator.java
│ │ │ │ │ ├── Registration.java
│ │ │ │ │ ├── RemovalCallback.java
│ │ │ │ │ ├── RequestContext.java
│ │ │ │ │ ├── RootContext.java
│ │ │ │ │ ├── RootContextLocator.java
│ │ │ │ │ ├── SimpleBeanLocator.java
│ │ │ │ │ ├── SingletonFactory.java
│ │ │ │ │ ├── SpringContextFactory.java
│ │ │ │ │ ├── SpringFactory.java
│ │ │ │ │ └── date
│ │ │ │ │ │ └── CtxDateFormatFactory.java
│ │ │ │ │ └── db
│ │ │ │ │ ├── SqlBuilder.java
│ │ │ │ │ ├── Table.java
│ │ │ │ │ ├── TableCreatorService.java
│ │ │ │ │ ├── TableDefinitionSource.java
│ │ │ │ │ ├── TableXmlHelper.java
│ │ │ │ │ ├── UseConnection.java
│ │ │ │ │ ├── dialects
│ │ │ │ │ ├── Dialect.java
│ │ │ │ │ ├── H2Dialect.java
│ │ │ │ │ ├── HqlDialect.java
│ │ │ │ │ └── PostgresDialect.java
│ │ │ │ │ └── types
│ │ │ │ │ ├── BinaryType.java
│ │ │ │ │ ├── CharacterType.java
│ │ │ │ │ ├── CharacterVaryingType.java
│ │ │ │ │ ├── FieldType.java
│ │ │ │ │ ├── FieldTypes.java
│ │ │ │ │ ├── Float8Type.java
│ │ │ │ │ ├── IntegerType.java
│ │ │ │ │ ├── LongType.java
│ │ │ │ │ └── TimestampType.java
│ │ │ └── io
│ │ │ │ └── milton
│ │ │ │ └── sync
│ │ │ │ ├── Archiver.java
│ │ │ │ ├── DbInitialiser.java
│ │ │ │ ├── DeltaListener.java
│ │ │ │ ├── DirWalker.java
│ │ │ │ ├── HttpBlobStore.java
│ │ │ │ ├── HttpBloomFilterHashCache.java
│ │ │ │ ├── HttpHashStore.java
│ │ │ │ ├── HttpUtils.java
│ │ │ │ ├── JdbcHashCache.java
│ │ │ │ ├── JdbcSyncStatusStore.java
│ │ │ │ ├── MemoryHashCache.java
│ │ │ │ ├── MinimalPutsBlobStore.java
│ │ │ │ ├── MinimalPutsHashStore.java
│ │ │ │ ├── SpliffySync.java
│ │ │ │ ├── SwingConflictResolver.java
│ │ │ │ ├── SyncCommand.java
│ │ │ │ ├── SyncJob.java
│ │ │ │ ├── SyncStatusStore.java
│ │ │ │ ├── Syncer.java
│ │ │ │ ├── SyncingDeltaListener.java
│ │ │ │ ├── Utils.java
│ │ │ │ ├── WriteThroughBlobStore.java
│ │ │ │ ├── WriteThroughHashStore.java
│ │ │ │ ├── event
│ │ │ │ ├── DownloadSyncEvent.java
│ │ │ │ ├── EventUtils.java
│ │ │ │ ├── FileChangedEvent.java
│ │ │ │ ├── FinishedSyncEvent.java
│ │ │ │ ├── ScanEvent.java
│ │ │ │ ├── TransferProgressEvent.java
│ │ │ │ └── UploadSyncEvent.java
│ │ │ │ └── triplets
│ │ │ │ ├── BerkeleyDbFileHashCache.java
│ │ │ │ ├── BlobDao.java
│ │ │ │ ├── BlobUtils.java
│ │ │ │ ├── BlockingBlobStore.java
│ │ │ │ ├── BlockingHashStore.java
│ │ │ │ ├── CrcDao.java
│ │ │ │ ├── DeltaGenerator.java
│ │ │ │ ├── DirWalker.java
│ │ │ │ ├── FastParser.java
│ │ │ │ ├── FileSystemWatchingService.java
│ │ │ │ ├── FileUpdatingMergingDeltaListener.java
│ │ │ │ ├── HttpTripletStore.java
│ │ │ │ ├── JdbcLocalTripletStore.java
│ │ │ │ ├── MemoryLocalTripletStore.java
│ │ │ │ ├── MemorySyncHashCache.java
│ │ │ │ ├── OneWayMergingDeltaListener.java
│ │ │ │ ├── ParentHashAwareTripletStore.java
│ │ │ │ ├── PausableTripletStore.java
│ │ │ │ ├── SyncHashCache.java
│ │ │ │ └── TripletStore.java
│ │ └── resources
│ │ │ ├── Images
│ │ │ ├── logo-dark.png
│ │ │ └── upload.png
│ │ │ └── log4j.properties
│ └── test
│ │ ├── java
│ │ └── io
│ │ │ └── milton
│ │ │ └── sync
│ │ │ └── triplets
│ │ │ └── DeltaGeneratorTest.java
│ │ └── resources
│ │ ├── branch1
│ │ ├── a
│ │ │ ├── a-changed.txt
│ │ │ ├── a-deleted.txt
│ │ │ └── a-not-changed.txt
│ │ └── c
│ │ │ └── c-not-changed.txt
│ │ ├── branch2
│ │ ├── a
│ │ │ ├── a-changed.txt
│ │ │ ├── a-new1.txt
│ │ │ └── a-not-changed.txt
│ │ └── c
│ │ │ └── c-not-changed.txt
│ │ └── branch3
│ │ └── a
│ │ ├── a-changed.txt
│ │ ├── a-deleted.txt
│ │ └── a-not-changed.txt
└── ~
│ ├── syncdb.h2.db
│ └── syncdb.trace.db
├── milton-cloud-vfs
├── mem.h2.db
├── nb-configuration.xml
├── nbactions.xml
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── io
│ │ └── milton
│ │ ├── cloud
│ │ ├── common
│ │ │ ├── CurrentDateService.java
│ │ │ ├── DefaultCurrentDateService.java
│ │ │ ├── MutableCurrentDateService.java
│ │ │ └── With.java
│ │ └── process
│ │ │ ├── AbstractRule.java
│ │ │ ├── ActionHandler.java
│ │ │ ├── AndRule.java
│ │ │ ├── BeanPropertyExpression.java
│ │ │ ├── ComparisonRule.java
│ │ │ ├── ConstantExpression.java
│ │ │ ├── ContainsRule.java
│ │ │ ├── Expression.java
│ │ │ ├── ListFilterExpression.java
│ │ │ ├── OrRule.java
│ │ │ ├── ProcessContext.java
│ │ │ ├── ProcessImpl.java
│ │ │ ├── ProcessInstance.java
│ │ │ ├── Rule.java
│ │ │ ├── State.java
│ │ │ ├── StateImpl.java
│ │ │ ├── StateProcess.java
│ │ │ ├── StateProcessBuilder.java
│ │ │ ├── TimeDependentRule.java
│ │ │ ├── TimerService.java
│ │ │ ├── Transition.java
│ │ │ ├── TransitionImpl.java
│ │ │ ├── Transitions.java
│ │ │ └── TrueRule.java
│ │ └── vfs
│ │ ├── content
│ │ └── DbHashStore.java
│ │ ├── data
│ │ ├── DataSession.java
│ │ └── NodesChangedEvent.java
│ │ └── db
│ │ ├── AbstractVfsVisitor.java
│ │ ├── AddressBook.java
│ │ ├── AttendeeRequest.java
│ │ ├── BaseEntity.java
│ │ ├── BaseProcess.java
│ │ ├── BlobHash.java
│ │ ├── Branch.java
│ │ ├── CalEvent.java
│ │ ├── CalEventProcess.java
│ │ ├── Calendar.java
│ │ ├── Commit.java
│ │ ├── Contact.java
│ │ ├── ContactExtendedProperty.java
│ │ ├── Credential.java
│ │ ├── FanoutEntry.java
│ │ ├── FanoutHash.java
│ │ ├── Group.java
│ │ ├── GroupFolder.java
│ │ ├── GroupInWebsite.java
│ │ ├── GroupMembership.java
│ │ ├── GroupRole.java
│ │ ├── ImprovedImplicitNamingStrategy.java
│ │ ├── ImprovedPhysicalNamingStrategy.java
│ │ ├── MembershipProcess.java
│ │ ├── NvPair.java
│ │ ├── NvSet.java
│ │ ├── OrgType.java
│ │ ├── Organisation.java
│ │ ├── PasswordCredential.java
│ │ ├── Profile.java
│ │ ├── Reminder.java
│ │ ├── Repository.java
│ │ ├── SubOrg.java
│ │ ├── Subordinate.java
│ │ ├── VfsAcceptor.java
│ │ ├── VfsVisitor.java
│ │ ├── Website.java
│ │ └── utils
│ │ ├── DbUtils.java
│ │ └── SessionManager.java
│ └── test
│ ├── java
│ └── ConflictTest.java
│ └── resources
│ ├── database.xml
│ └── log4j.properties
├── nb-configuration.xml
├── nbactions.xml
├── pom.xml
├── v2
└── velocity.log
/.gitignore:
--------------------------------------------------------------------------------
1 | /spliffy-sync-app/branding/target/userdir/var/cache/netigso/org.eclipse.core.runtime/.manager/
2 | /spliffy-sync-app/branding/target/userdir/var/cache/netigso/org.eclipse.equinox.app/.manager/
3 | /spliffy-sync-app/branding/target/userdir/var/cache/netigso/org.eclipse.osgi/.manager/
4 | /spliffy-sync-app/module/target/userdir/var/cache/netigso/org.eclipse.core.runtime/.manager/
5 | /spliffy-sync-app/module/target/userdir/var/cache/netigso/org.eclipse.equinox.app/.manager/
6 | /spliffy-sync-app/module/target/userdir/var/cache/netigso/org.eclipse.osgi/.manager/
7 | /milton-cloud-lib/target/
8 | /milton-cloud-server/target/
9 | /milton-cloud-sync/target/
10 | /milton-cloud-sync-app/application/target/
11 | /milton-cloud-sync-app/branding/target/
12 | /milton-cloud-sync-app/module/target/
13 | /milton-cloud-vfs/target/
14 | /milton-cloud-server/velocity.log
15 | /milton-cloud-server-api/target/
16 | /external/ckeditor/target/
17 | /external/jstree/target/
18 | /external/colorpicker/target/
19 | /milton-cloud-blobby/target/
20 | /.idea
21 | *.iml
22 | /milton-cloud-server/src/test/resources/milton.license.properties
23 | /milton-cloud-server/src/test/resources/milton.license.sig
24 | /examples/mc-vfs-gettingstarted/target/
25 | .project
26 | .settings/
27 | milton-cloud-sync/.classpath
28 | milton-cloud-sync/.project
29 | milton-cloud-sync/.settings/
30 | milton-cloud-vfs/.classpath
31 | milton-cloud-vfs/.project
32 | milton-cloud-vfs/.settings/
33 | /sync-tool/sync-gui/target/
34 | /sync-tool/sync-tool-gui/target/
35 | /sync-tool/branding/target/
36 | /sync-tool/application/target/
37 | /SyncTool/SyncTool/branding/target/
38 | /SyncTool/SyncTool/SyncToolGui/target/
39 | /SyncTool/SyncTool/application/target/
40 | /SyncTool/SyncTool/target/
41 | /milton-cloud-tool/branding/target/
42 | /milton-cloud-tool/application/target/
43 | /milton-cloud-tool/milton-cloud-tool-gui/target/
44 | /milton-cloud/milton-cloud/milton-cloud-tool/target/
45 | /milton-cloud/milton-cloud/branding/target/
46 | /milton-cloud/milton-cloud/application/target/
47 | /milton-cloud-sync-app/milton-cloud-tool/target/
--------------------------------------------------------------------------------
/aa:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/aa
--------------------------------------------------------------------------------
/db-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/db-diagram.png
--------------------------------------------------------------------------------
/examples/mc-vfs-gettingstarted/nbactions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CUSTOM-jetty:run
5 | jetty:run
6 |
7 | jetty:run
8 |
9 |
10 |
11 | CUSTOM-jetty:stop jetty:run
12 | jetty:stop jetty:run
13 |
14 | jetty:stop
15 | jetty:run
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/mc-vfs-gettingstarted/src/main/resources/default.properties:
--------------------------------------------------------------------------------
1 | # DATABASE
2 |
3 | hibernate.dialect=org.hibernate.dialect.H2Dialect
4 | hibernate.show_sql=false
5 | jdbc.driverClassName=org.h2.Driver
6 | jdbc.url=jdbc:h2:file:target/db;MVCC=TRUE
7 | jdbc.username=sa
8 | jdbc.password=
9 |
--------------------------------------------------------------------------------
/examples/mc-vfs-gettingstarted/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Set root logger level to DEBUG and its only appender to A1.
2 | log4j.rootLogger=INFO, A1
3 |
4 | # A1 is set to be a ConsoleAppender.
5 | log4j.appender.A1=org.apache.log4j.ConsoleAppender
6 |
7 | # A1 uses PatternLayout.
8 | log4j.appender.A1.layout=org.apache.log4j.PatternLayout
9 | log4j.appender.A1.layout.ConversionPattern=%-5p %c %x - %m%n
10 |
11 | log4j.logger.net.sf.json.JSONObject=WARN
12 |
13 | log4j.logger.io.milton=INFO
14 | log4j.logger.io.milton.http.AuthenticationService=INFO
15 | log4j.logger.io.milton.http.annotated=INFO
16 | log4j.logger.io.milton.http.entity=INFO
17 | log4j.logger.io.milton.http.webdav.PropFindPropertyBuilder=INFO
18 | log4j.logger.io.milton.property.BeanPropertySource=INFO
19 | log4j.logger.io.milton.http.http11.auth=INFO
20 |
--------------------------------------------------------------------------------
/examples/mc-vfs-gettingstarted/src/main/resources/milton.license.properties:
--------------------------------------------------------------------------------
1 | #Wed Feb 13 11:57:32 NZDT 2013
2 | CompanyName=McEvoy Software Ltd
3 | Help=If you need any help please get in touch\! http\://milton.io/contact
4 | License=Limited time trial commercial
5 | Expires=2013-05-14
6 |
7 |
--------------------------------------------------------------------------------
/examples/mc-vfs-gettingstarted/src/main/resources/milton.license.sig:
--------------------------------------------------------------------------------
1 | MC0CFQCKjzQGTR7G5G6BEc3IQrh1AEyaVAIUDT5prlSyb3Df5ChYjXT8DPtqpp8=
--------------------------------------------------------------------------------
/examples/mc-vfs-gettingstarted/src/main/resources/miltonContext.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/examples/mc-vfs-gettingstarted/src/main/resources/rootContext.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | classpath:default.properties
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/mc-vfs-gettingstarted/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 | contextConfigLocation
9 | classpath:rootContext.xml
10 |
11 |
12 | org.springframework.web.context.ContextLoaderListener
13 |
14 |
15 |
16 | openSessionInViewFilter
17 |
18 | org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
19 |
20 |
21 | singleSession
22 | true
23 |
24 |
25 |
26 |
27 | openSessionInViewFilter
28 | /*
29 |
30 |
31 |
32 | miltonFilter
33 | io.milton.servlet.SpringMiltonFilter
34 |
35 | milton.exclude.paths
36 | /static,/templates
37 |
38 |
39 | contextConfigLocation
40 | classpath:miltonContext.xml
41 |
42 |
43 |
44 |
45 | miltonFilter
46 | /*
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/examples/mc-vfs-gettingstarted/src/main/webapp/templates/directory.jsp:
--------------------------------------------------------------------------------
1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2 | <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Directory: ${model.directory.name}/
11 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/application/nb-configuration.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
16 | JDK_1.8u65
17 |
18 |
19 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/application/src/test/java/io/milton/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package io.milton;
2 |
3 | import junit.framework.Test;
4 | import org.netbeans.junit.NbModuleSuite;
5 | import org.netbeans.junit.NbTestCase;
6 |
7 | public class ApplicationTest extends NbTestCase {
8 |
9 | public static Test suite() {
10 | return NbModuleSuite.createConfiguration(ApplicationTest.class).
11 | gui(false).
12 | // failOnMessage(Level.WARNING). // works at least in RELEASE71
13 | // failOnException(Level.INFO).
14 | enableClasspathModules(false).
15 | clusters(".*").
16 | suite(); // RELEASE71+, else use NbModuleSuite.create(NbModuleSuite.createConfiguration(...))
17 | }
18 |
19 | public ApplicationTest(String n) {
20 | super(n);
21 | }
22 |
23 | public void testApplication() {
24 | // pass if there are merely no warnings/exceptions
25 | /* Example of using Jelly Tools (additional test dependencies required) with gui(true):
26 | new ActionNoBlock("Help|About", null).performMenu();
27 | new NbDialogOperator("About").closeByButton();
28 | */
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/application/~/syncdb.h2.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync-app/application/~/syncdb.h2.db
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | io.milton
7 | milton-cloud-sync-app-parent
8 | 1.2.1
9 |
10 |
11 | milton-cloud-branding
12 | nbm
13 |
14 | milton-cloud-branding
15 |
16 |
17 | UTF-8
18 |
19 |
20 |
21 |
22 | org.netbeans.api
23 | org-netbeans-api-annotations-common
24 | ${netbeans.version}
25 |
26 |
27 |
28 |
29 |
30 |
31 | org.codehaus.mojo
32 | nbm-maven-plugin
33 |
34 |
35 | org.apache.maven.plugins
36 | maven-jar-plugin
37 |
38 |
39 | true
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/nbm-branding/core/core.jar/org/netbeans/core/startup/Bundle.properties:
--------------------------------------------------------------------------------
1 | currentVersion=milton-cloud {0}
2 | LBL_splash_window_title=Starting milton-cloud
3 | SPLASH_HEIGHT=100
4 | SPLASH_WIDTH=126
5 | SplashProgressBarBounds=0,83,126,6
6 | SplashRunningTextBounds=2,78,119,3
7 | SplashRunningTextFontSize=6
8 | SplashShowProgressBar=false
9 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/nbm-branding/core/core.jar/org/netbeans/core/startup/frame.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync-app/branding/src/main/nbm-branding/core/core.jar/org/netbeans/core/startup/frame.gif
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/nbm-branding/core/core.jar/org/netbeans/core/startup/frame32.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync-app/branding/src/main/nbm-branding/core/core.jar/org/netbeans/core/startup/frame32.gif
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/nbm-branding/core/core.jar/org/netbeans/core/startup/frame48.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync-app/branding/src/main/nbm-branding/core/core.jar/org/netbeans/core/startup/frame48.gif
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/nbm-branding/core/core.jar/org/netbeans/core/startup/splash.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync-app/branding/src/main/nbm-branding/core/core.jar/org/netbeans/core/startup/splash.gif
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/nbm-branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/Bundle.properties:
--------------------------------------------------------------------------------
1 | Mode.Editor.DragAndDrop.Enabled=false
2 | Mode.Sliding.Enabled=false
3 | Mode.View.DragAndDrop.Enabled=false
4 | TopComponent.DragAndDrop.Enabled=false
5 | TopComponent.Sliding.Enabled=false
6 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/nbm-branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties:
--------------------------------------------------------------------------------
1 | CTL_MainWindow_Title=milton-cloud {0}
2 | CTL_MainWindow_Title_No_Project=milton-cloud {0}
3 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/nbm-branding/modules/org-netbeans-core.jar/org/netbeans/core/ui/Bundle.properties:
--------------------------------------------------------------------------------
1 | LBL_ProductInformation=milton-cloud
2 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/nbm/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | OpenIDE-Module-Localizing-Bundle: io/milton/branding/Bundle.properties
3 | AutoUpdate-Essential-Module: true
4 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/branding/src/main/resources/io/milton/branding/Bundle.properties:
--------------------------------------------------------------------------------
1 | # Localized module labels. Defaults taken from POM (, , ) if unset.
2 | #OpenIDE-Module-Name=
3 | #OpenIDE-Module-Short-Description=
4 | #OpenIDE-Module-Long-Description=
5 | #OpenIDE-Module-Display-Category=
6 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/milton-cloud-tool/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | io.milton
6 | milton-cloud-sync-app-parent
7 | 1.2.1
8 |
9 | milton-cloud-tool
10 | nbm
11 |
12 |
13 |
14 | org.codehaus.mojo
15 | nbm-maven-plugin
16 | true
17 |
18 |
19 | org.apache.maven.plugins
20 | maven-jar-plugin
21 |
22 | true
23 |
24 |
25 |
26 |
27 |
28 |
29 | org.netbeans.api
30 | org-netbeans-api-annotations-common
31 | ${netbeans.version}
32 |
33 |
34 | ${project.groupId}
35 | milton-cloud-sync
36 | 1.2.4
37 |
38 |
39 | org.netbeans.api
40 | org-openide-windows
41 | ${netbeans.version}
42 |
43 |
44 | org.netbeans.api
45 | org-openide-util
46 | ${netbeans.version}
47 |
48 |
49 | org.netbeans.api
50 | org-openide-util-ui
51 | ${netbeans.version}
52 |
53 |
54 | org.netbeans.api
55 | org-openide-util-lookup
56 | ${netbeans.version}
57 |
58 |
59 | org.netbeans.api
60 | org-openide-awt
61 | ${netbeans.version}
62 |
63 |
64 | org.netbeans.api
65 | org-netbeans-modules-settings
66 | ${netbeans.version}
67 |
68 |
69 | org.json
70 | json
71 | 20160810
72 | jar
73 |
74 |
75 |
76 |
77 | UTF-8
78 |
79 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/milton-cloud-tool/src/main/java/guiTool/Helper.java:
--------------------------------------------------------------------------------
1 | package guiTool;
2 |
3 | /*
4 | * To change this license header, choose License Headers in Project Properties.
5 | * To change this template file, choose Tools | Templates
6 | * and open the template in the editor.
7 | */
8 |
9 |
10 | import java.io.BufferedReader;
11 | import java.io.InputStreamReader;
12 | import java.net.Authenticator;
13 | import java.net.InetSocketAddress;
14 | import java.net.PasswordAuthentication;
15 | import java.net.Socket;
16 | import java.net.URL;
17 | import java.util.ArrayList;
18 | import javax.swing.JOptionPane;
19 | import org.json.JSONArray;
20 | import org.json.JSONException;
21 | import org.json.JSONObject;
22 |
23 | /**
24 | *
25 | * @author ibraheem
26 | */
27 | public class Helper {
28 |
29 | public static final boolean checkInternet() {
30 |
31 | try {
32 | Socket socket = new Socket();
33 | InetSocketAddress add = new InetSocketAddress("www.google.com", 80);
34 | socket.connect(add, 3000);
35 | return true;
36 | } catch (Exception e) {
37 | JOptionPane.showMessageDialog(null, "The server or your internet connection could be down.", "connection test", JOptionPane.ERROR_MESSAGE);
38 | return false;
39 | }
40 |
41 | }
42 |
43 | public static String readUrl(String urlString, final String userid, final String password) throws Exception {
44 |
45 | BufferedReader reader = null;
46 | StringBuilder buffer = null;
47 | try {
48 | URL url = new URL(urlString);
49 |
50 | Authenticator.setDefault(new Authenticator() {
51 | @Override
52 | protected PasswordAuthentication getPasswordAuthentication() {
53 | return new PasswordAuthentication(userid, password.toCharArray());
54 | }
55 | });
56 | InputStreamReader s = new InputStreamReader(url.openStream());
57 | // System.out.println("getEncoding " + s.getEncoding());
58 | reader = new BufferedReader(s);
59 |
60 | buffer = new StringBuilder();
61 | int read;
62 | char[] chars = new char[1024];
63 | while ((read = reader.read(chars)) != -1) {
64 | buffer.append(chars, 0, read);
65 | }
66 |
67 | } catch (Exception e) {
68 | System.out.println("Exception " +e.getMessage());
69 | // JOptionPane.showMessageDialog(null, "The server or your internet connection could be down.", "connection test", JOptionPane.ERROR_MESSAGE);
70 |
71 | } finally {
72 | if (reader != null) {
73 | reader.close();
74 | }
75 | }
76 | return buffer.toString();
77 | }
78 |
79 | public static ArrayList getDataFromJson(String json) {
80 | ArrayList list = new ArrayList<>();
81 |
82 | try {
83 | JSONArray array = new JSONArray(json);
84 | JSONObject jSONObject;
85 | for (int i = 0; i < array.length(); i++) {
86 | jSONObject = new JSONObject(array.get(i).toString());
87 | list.add((String) jSONObject.get("name"));
88 |
89 | }
90 | } catch (JSONException ex) {
91 | System.out.println(ex.getMessage());
92 | }
93 | return list;
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/milton-cloud-tool/src/main/java/guiTool/base.java:
--------------------------------------------------------------------------------
1 | package guiTool;
2 |
3 | /*
4 | * To change this template, choose Tools | Templates
5 | * and open the template in the editor.
6 | */
7 |
8 |
9 | import java.io.File;
10 | import java.io.IOException;
11 | import java.io.RandomAccessFile;
12 | import java.nio.channels.FileChannel;
13 | import java.nio.channels.FileLock;
14 |
15 | /**
16 | *
17 | * @author ibraheem
18 | */
19 | public class base {
20 |
21 | SyncToolTopComponent main = new SyncToolTopComponent();
22 |
23 | public void run() {
24 | main.setVisible(true);
25 | }
26 |
27 | public static File file;
28 | /* */ public static FileChannel filechannel;
29 | /* */ public static FileLock fileLock;
30 |
31 | public static void main(String args[]) {
32 |
33 | try {
34 | file = new File("Key");
35 |
36 | if (file.exists()) {
37 | file.delete();
38 | }
39 |
40 | filechannel = new RandomAccessFile(file, "rw").getChannel();
41 | fileLock = filechannel.tryLock();
42 |
43 | if (fileLock == null) {
44 | filechannel.close();
45 | throw new RuntimeException("errr");
46 | }
47 | Thread shut = new Thread(new Runnable() {
48 |
49 | @Override
50 | public void run() {
51 |
52 | }
53 |
54 | });
55 |
56 | Runtime.getRuntime().addShutdownHook(shut);
57 |
58 | protect();
59 | } catch (IOException | RuntimeException e) {
60 | System.out.println(e.getMessage());
61 |
62 | System.exit(0);
63 |
64 | }
65 | }
66 |
67 | public static void unlock() {
68 | try {
69 | if (fileLock != null) {
70 | fileLock.release();
71 | filechannel.close();
72 | file.delete();
73 | }
74 | } catch (Exception e) {
75 | }
76 | }
77 |
78 | //will prevent copy
79 | private static void protect() {
80 | try {
81 | javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
82 |
83 | } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
84 | ex.printStackTrace();
85 | }
86 | base b = new base();
87 | b.run();
88 | }
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/milton-cloud-tool/src/main/nbm/manifest.mf:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | OpenIDE-Module-Localizing-Bundle: /Bundle.properties
3 | OpenIDE-Module-Requires: org.openide.windows.WindowManager
4 |
5 |
--------------------------------------------------------------------------------
/milton-cloud-sync-app/milton-cloud-tool/src/main/resources/Bundle.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync-app/milton-cloud-tool/src/main/resources/Bundle.properties
--------------------------------------------------------------------------------
/milton-cloud-sync-app/milton-cloud-tool/src/main/resources/images/logo-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync-app/milton-cloud-tool/src/main/resources/images/logo-dark.png
--------------------------------------------------------------------------------
/milton-cloud-sync-app/milton-cloud-tool/src/main/resources/images/upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync-app/milton-cloud-tool/src/main/resources/images/upload.png
--------------------------------------------------------------------------------
/milton-cloud-sync-app/milton-cloud-tool/~/syncdb.h2.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync-app/milton-cloud-tool/~/syncdb.h2.db
--------------------------------------------------------------------------------
/milton-cloud-sync-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | io.milton
7 | milton-cloud-sync-app-parent
8 | 1.2.1
9 | pom
10 |
11 | milton-cloud-sync-app-parent
12 |
13 |
14 |
19 |
20 | netbeans
21 | NetBeans
22 | http://bits.netbeans.org/nexus/content/groups/netbeans/
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | org.codehaus.mojo
31 | nbm-maven-plugin
32 | 3.13
33 | true
34 |
35 | ${brandingToken}
36 | ${brandingToken}
37 |
38 |
39 |
40 |
41 | org.apache.maven.plugins
42 | maven-compiler-plugin
43 | 2.5.1
44 |
45 | 1.7
46 | 1.7
47 |
48 |
49 |
50 | org.apache.maven.plugins
51 | maven-jar-plugin
52 | 2.4
53 |
54 |
55 |
56 |
57 |
58 |
59 | branding
60 | application
61 | milton-cloud-tool
62 |
63 |
64 |
65 | RELEASE81
66 | miltoncloud
67 |
68 |
69 |
--------------------------------------------------------------------------------
/milton-cloud-sync/Key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync/Key
--------------------------------------------------------------------------------
/milton-cloud-sync/nbactions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | run
5 |
6 | process-classes
7 | org.codehaus.mojo:exec-maven-plugin:1.2:exec
8 |
9 |
10 | -classpath %classpath GUISync.base
11 | java
12 | runtime
13 |
14 |
15 |
16 | debug
17 |
18 | process-classes
19 | org.codehaus.mojo:exec-maven-plugin:1.2:exec
20 |
21 |
22 | -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath GUISync.base
23 | java
24 | runtime
25 | true
26 |
27 |
28 |
29 | profile
30 |
31 | process-classes
32 | org.codehaus.mojo:exec-maven-plugin:1.2:exec
33 |
34 |
35 | -classpath %classpath GUISync.base
36 | ${profiler.java}
37 | profile
38 |
39 |
40 |
41 | CUSTOM-deploy
42 | deploy
43 |
44 | deploy
45 |
46 |
47 |
48 | CUSTOM-dependency:list
49 | dependency:list
50 |
51 | dependency:list
52 |
53 |
54 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/io/ChunkStore.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.io;
2 |
3 | public interface ChunkStore extends ChunkWriter{
4 |
5 | /** retrieve the chunk at position i (zero indexed)
6 | */
7 | byte[] getChunk(int i);
8 |
9 | /**
10 | * delete any chunks which might exist
11 | */
12 | void deleteChunks();
13 | }
14 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/io/ChunkWriter.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.io;
2 |
3 | public interface ChunkWriter {
4 | /** create a new chunk at position i (zero indexed) with the entire
5 | * byte array in data
6 | */
7 | void newChunk(int i, byte[] data);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/io/ChunkingInputStream.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.io;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | public class ChunkingInputStream extends InputStream{
10 | private static final Logger log = LoggerFactory.getLogger(ChunkingInputStream.class);
11 | final ChunkStore store;
12 |
13 | private int chunkNum;
14 | private int pos = -1;
15 | private byte[] currentChunk;
16 |
17 | public ChunkingInputStream(ChunkStore store) {
18 | this.store = store;
19 | this.currentChunk = store.getChunk(chunkNum++);
20 | }
21 |
22 | @Override
23 | public int read() throws IOException {
24 | if( currentChunk == null ) return -1;
25 | pos++;
26 | if( pos >= currentChunk.length ) { // if first, or have exhausted current, get next chunk
27 | currentChunk = store.getChunk(chunkNum++);
28 | if( currentChunk == null ) return -1; // EOF. no more data
29 | pos = 0;
30 | }
31 | int i = currentChunk[pos] & 0xff;
32 | return i;
33 | }
34 |
35 | public void writeTo(OutputStream out) throws IOException {
36 | long t = System.currentTimeMillis();
37 | boolean done = (currentChunk == null || currentChunk.length==0);
38 | while( !done ) {
39 | out.write(currentChunk);
40 | log.debug("chunk: " + chunkNum + " - " + currentChunk.length);
41 |
42 | currentChunk = store.getChunk(chunkNum++);
43 | done = (currentChunk == null || currentChunk.length==0);
44 | }
45 | t = System.currentTimeMillis() - t;
46 | log.debug("transmission time: " + t + "ms");
47 | }
48 | // public synchronized int read(byte b[], int off, int len) {
49 | // log.debug("read-" + off + " - " + len);
50 | // log.debug(" chunk: " + chunkNum + " size:" + currentChunk.length);
51 | // if (b == null) {
52 | // throw new NullPointerException();
53 | // } else if (off < 0 || len < 0 || len > b.length - off) {
54 | // throw new IndexOutOfBoundsException();
55 | // }
56 | //
57 | // int nextLen = 0;
58 | // int thisLen = len;
59 | // if( thisLen+off > currentChunk.length-1 ) {
60 | // nextLen = off + thisLen - currentChunk.length - 1;
61 | // thisLen = currentChunk.length - off;
62 | // log.debug(" nextLen: " + nextLen);
63 | // log.debug(" thisLen: " + thisLen);
64 | // }
65 | // log.debug("arraycopy " + currentChunk.length + "," + pos + "," + b.length + "," + off + "," + thisLen);
66 | // System.arraycopy(currentChunk, pos, b, off, thisLen);
67 | // pos += thisLen;
68 | // int nextBytes = 0;
69 | // if( nextLen > 0 ) {
70 | // nextBytes = read(b,off+thisLen,nextLen);
71 | // }
72 | // return len;
73 | // }
74 |
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/io/ChunkingOutputStream.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.io;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.OutputStream;
6 |
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | public class ChunkingOutputStream extends OutputStream {
11 |
12 | private static final Logger log = LoggerFactory.getLogger( ChunkingOutputStream.class );
13 | final ChunkWriter chunkWriter;
14 | final ByteArrayOutputStream chunkInProgress;
15 | final int chunkSize;
16 | private long count;
17 | private int currentChunk;
18 |
19 | public ChunkingOutputStream( ChunkWriter chunkWriter, int chunkSize ) {
20 | this.chunkWriter = chunkWriter;
21 | this.chunkSize = chunkSize;
22 | this.chunkInProgress = new ByteArrayOutputStream( chunkSize );
23 | }
24 |
25 | @Override
26 | public void write( byte[] b ) throws IOException {
27 | count += b.length;
28 | if( chunkInProgress.size() >= chunkSize ) {
29 | flushChunk();
30 | }
31 |
32 | chunkInProgress.write( b );
33 | }
34 |
35 | @Override
36 | public void write( int b ) throws IOException {
37 | count++;
38 | if( chunkInProgress.size() >= chunkSize ) {
39 | flushChunk();
40 | }
41 | chunkInProgress.write( b );
42 | }
43 |
44 | @Override
45 | public void write( byte[] b, int off, int len ) throws IOException {
46 | if( chunkInProgress.size() >= chunkSize ) {
47 | flushChunk();
48 | }
49 | count += len;
50 | chunkInProgress.write( b, off, len );
51 | }
52 |
53 | private void flushChunk() {
54 | if( chunkInProgress.size() == 0 ) {
55 | return;
56 | }
57 | byte[] arr = chunkInProgress.toByteArray();
58 | chunkWriter.newChunk( currentChunk++, arr );
59 | chunkInProgress.reset();
60 | }
61 |
62 | @Override
63 | public void flush() throws IOException {
64 | flushChunk();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/io/ReadingException.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.io;
2 |
3 | import java.io.IOException;
4 |
5 | public class ReadingException extends IOException{
6 | public ReadingException(IOException cause) {
7 | super(cause);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/io/WritingException.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.io;
2 |
3 | import java.io.IOException;
4 |
5 | public class WritingException extends IOException{
6 | public WritingException(IOException cause) {
7 | super(cause);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/utils/ElementList.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.utils;
2 |
3 | import java.util.ArrayList;
4 | import org.w3c.dom.Element;
5 | import org.w3c.dom.Node;
6 | import org.w3c.dom.NodeList;
7 |
8 | public class ElementList extends ArrayList {
9 |
10 | public ElementList(NodeList nodes) {
11 | for (int i = 0; i < nodes.getLength(); i++) {
12 | Node n = nodes.item(i);
13 | if( n instanceof Element ) {
14 | add( (Element)n );
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/utils/IntegerUtils.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.utils;
2 |
3 | public class IntegerUtils {
4 |
5 | public IntegerUtils() {
6 | }
7 |
8 | /** Returns true if the specified value exists in the array
9 | */
10 | public static boolean isInArray( int[] array, int valueToCheck) {
11 | for( int i=0; i {
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/utils/StreamWriter.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.utils;
2 |
3 | import java.io.OutputStream;
4 |
5 | public interface StreamWriter extends With{
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/utils/TypeUtils.java:
--------------------------------------------------------------------------------
1 |
2 | package com.bradmcevoy.utils;
3 |
4 | public class TypeUtils {
5 |
6 | }
7 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/utils/With.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.utils;
2 |
3 | public interface With {
4 | O use(T t) throws Exception;
5 | }
6 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/utils/entities.properties:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/version/Block.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.version;
2 |
3 | /**
4 | * Represents a block of data in a versioned file's block map
5 | *
6 | * @author brad
7 | */
8 | public interface Block {
9 | long getBlockSize();
10 |
11 | int getChecksum();
12 | }
13 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/version/BlockStore.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.version;
2 |
3 | /**
4 | * Represents a means of accessing blocks of data for a file.
5 | *
6 | * @author brad
7 | */
8 | public interface BlockStore {
9 | Block firstBlock();
10 | Block nextBlock(Block block);
11 | }
12 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/bradmcevoy/version/VersioningOutputStream.java:
--------------------------------------------------------------------------------
1 | package com.bradmcevoy.version;
2 |
3 | import com.bradmcevoy.io.*;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.IOException;
6 | import java.io.OutputStream;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | public class VersioningOutputStream extends OutputStream{
11 |
12 | private static final Logger log = LoggerFactory.getLogger(VersioningOutputStream.class);
13 |
14 | final ChunkWriter chunkWriter;
15 | final ByteArrayOutputStream chunkInProgress;
16 | final int chunkSize;
17 |
18 | private long count;
19 | private int currentChunk;
20 |
21 | public VersioningOutputStream(ChunkWriter chunkWriter, int chunkSize) {
22 | this.chunkWriter = chunkWriter;
23 | this.chunkSize = chunkSize;
24 | this.chunkInProgress = new ByteArrayOutputStream(chunkSize);
25 | }
26 |
27 |
28 |
29 | @Override
30 | public void write( byte[] b ) throws IOException {
31 | count+=b.length;
32 | if( chunkInProgress.size() >= chunkSize ) {
33 | flushChunk();
34 | }
35 |
36 | chunkInProgress.write(b);
37 | }
38 |
39 |
40 | public void write(int b) throws IOException {
41 | count++;
42 | if( chunkInProgress.size() >= chunkSize ) {
43 | flushChunk();
44 | }
45 | chunkInProgress.write(b);
46 | }
47 |
48 | @Override
49 | public void write(byte[] b, int off, int len) throws IOException {
50 | if( chunkInProgress.size() >= chunkSize ) {
51 | flushChunk();
52 | }
53 | count+=len;
54 | chunkInProgress.write(b, off, len);
55 | }
56 |
57 |
58 |
59 | private void flushChunk() {
60 | if( chunkInProgress.size() == 0 ) {
61 | return ;
62 | }
63 | byte[] arr = chunkInProgress.toByteArray();
64 | chunkWriter.newChunk(currentChunk++,arr);
65 | chunkInProgress.reset();
66 | }
67 |
68 | @Override
69 | public void flush() throws IOException {
70 | flushChunk();
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/common/Service.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.common;
2 |
3 | /**
4 | * Represents some service which can be controlled (ie started and stopped)
5 | *
6 | * @author brad
7 | */
8 | public interface Service {
9 | /**
10 | * Start the service. Until this is called the service should not be functional
11 | */
12 | void start();
13 |
14 | /**
15 | * The service should be made unavailable, however it should be able to
16 | * be starte again
17 | *
18 | */
19 | void stop();
20 | }
21 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/common/Withee.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.common;
2 |
3 | /**
4 | * General purpose interface for consuming a callback for some type. Typically
5 | * used in "with" style blocks:
6 | *
7 | * someRsourceProvider.with(new Withee() {
8 | * public void with(Resource r) {
9 | * ... do something with the resource
10 | * }
11 | * }
12 | *
13 | * @author bradm
14 | */
15 | public interface Withee {
16 | void with(T t) throws Exception;
17 | }
18 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/config/ConfigurationException.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.config;
2 |
3 |
4 | public class ConfigurationException extends Exception {
5 | private static final long serialVersionUID = 1L;
6 |
7 | public ConfigurationException(String msg) {
8 | super(msg);
9 | }
10 |
11 | public ConfigurationException(String context, Exception cause) {
12 | super(context,cause);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/Accessor.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | public interface Accessor extends Dependent{
4 | public void preExecute( Context context );
5 | public void postExecute( Context context );
6 | }
7 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/BeanFactory.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | *
8 | */
9 | public class BeanFactory implements Factory {
10 |
11 | public static final String SCOPE_APP = "app";
12 | public static final String SCOPE_REQUEST = "request";
13 |
14 | private Class beanClass;
15 | private Class[] keyClasses;
16 | private String scope = SCOPE_APP;
17 |
18 | public Class[] keyClasses() {
19 | return keyClasses;
20 | }
21 |
22 | public String[] keyIds() {
23 | return null;
24 | }
25 |
26 | public Registration insert(RootContext context, Context requestContext) {
27 | Object o = instantiateBean();
28 | if( isRequestScope() ) {
29 | return requestContext.put(o);
30 | } else {
31 | return context.put(o);
32 | }
33 | }
34 |
35 | public void init(RootContext context) {
36 |
37 | }
38 |
39 | public void destroy() {
40 |
41 | }
42 |
43 | public void onRemove(Object item) {
44 |
45 | }
46 |
47 | public String getBeanClass() {
48 | return beanClass.getCanonicalName();
49 | }
50 |
51 | public void setBeanClass(String beanClass) {
52 | try {
53 | this.beanClass = Class.forName(beanClass);
54 | } catch (ClassNotFoundException ex) {
55 | throw new RuntimeException(beanClass, ex);
56 | }
57 | if( this.keyClasses == null ) this.keyClasses = this.beanClass.getInterfaces();
58 | }
59 |
60 | public String getKeyClasses() {
61 | String s = "";
62 | for( Class c : keyClasses ) {
63 | s = s + c.getCanonicalName() + ",";
64 | }
65 | return s;
66 | }
67 |
68 | public void setKeyClasses(String keyClasses) {
69 | String[] arr = keyClasses.split(",");
70 | List list = new ArrayList();
71 | for( String s : arr) {
72 | try {
73 | Class i = Class.forName(s);
74 | list.add(i);
75 | } catch (ClassNotFoundException ex) {
76 | throw new RuntimeException(s, ex);
77 | }
78 | }
79 | this.keyClasses = new Class[list.size()];
80 | list.toArray(this.keyClasses);
81 | }
82 |
83 | public String getScope() {
84 | return scope;
85 | }
86 |
87 | public void setScope(String scope) {
88 | if( scope.equals(SCOPE_APP) || scope.equals(SCOPE_REQUEST)) {
89 | this.scope = scope;
90 | } else {
91 | throw new RuntimeException("Scope attribute on BeanFactory must be " + SCOPE_APP + " or " + SCOPE_REQUEST + " not: " + scope);
92 | }
93 | }
94 |
95 | private Object instantiateBean() {
96 | try {
97 | return beanClass.newInstance();
98 | } catch (InstantiationException ex) {
99 | throw new RuntimeException(ex);
100 | } catch (IllegalAccessException ex) {
101 | throw new RuntimeException(ex);
102 | }
103 | }
104 |
105 | private boolean isRequestScope() {
106 | return scope.equals(SCOPE_REQUEST);
107 | }
108 |
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/BeanLocator.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | /**
4 | *
5 | */
6 | public interface BeanLocator {
7 | Object locateBean(Context context);
8 | }
9 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/BeanWrapper.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | /**
4 | *
5 | * @author brad
6 | */
7 | public class BeanWrapper implements Factory {
8 |
9 | private Object bean;
10 |
11 | public Class[] keyClasses() {
12 | return null;
13 | }
14 |
15 | public String[] keyIds() {
16 | return null;
17 | }
18 |
19 | public Registration insert(RootContext context, Context requestContext) {
20 | throw new UnsupportedOperationException( "should already be in context");
21 | }
22 |
23 | public void init(RootContext context) {
24 | context.put( bean);
25 | }
26 |
27 | public void destroy() {
28 |
29 | }
30 |
31 | public void onRemove(Object item) {
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/ClassBeanLocator.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | /**
4 | *
5 | */
6 | public class ClassBeanLocator implements BeanLocator{
7 |
8 | final Class classToFind;
9 |
10 | public ClassBeanLocator(Class classToFind) {
11 | this.classToFind = classToFind;
12 | }
13 |
14 | public Object locateBean(Context context) {
15 | return context.get(classToFind);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/ClassNotInContextException.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | /**
4 | * Represents a missing class
5 | *
6 | * @author brad
7 | */
8 | public class ClassNotInContextException extends RuntimeException{
9 | private static final long serialVersionUID = 1L;
10 | private final Class missing;
11 |
12 | public ClassNotInContextException( Class missing ) {
13 | super("The requested class is not in context: " + missing.getCanonicalName());
14 | this.missing = missing;
15 | }
16 |
17 | public Class getMissing() {
18 | return missing;
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/Contextual.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | /** This interface represents those classes which contain context
4 | */
5 | public interface Contextual {
6 | public T get(String id);
7 |
8 | public T get(Class c);
9 | }
10 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/CtxRootFolderFactory.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.FileNotFoundException;
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.util.Properties;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | public class CtxRootFolderFactory implements Factory {
13 | private static final Logger log = LoggerFactory.getLogger(CtxRootFolderFactory.class);
14 | private File file;
15 | private static String[] keys = {"rootFolder"};
16 |
17 | public static final String KEY_ROOT_FOLDER = "rootFolder";
18 |
19 | public CtxRootFolderFactory() {
20 | log.debug("Created: CtxRootFolderFactory");
21 | }
22 |
23 | public Class[] keyClasses() {
24 | return null;
25 | }
26 |
27 | public String[] keyIds() {
28 | return keys;
29 | }
30 |
31 | public Registration insert(RootContext context, Context requestContext) {
32 | Registration reg = (Registration)context.put(file,this);
33 | return reg;
34 | }
35 |
36 | public void init(RootContext context) {
37 | log.debug("CtxRootFolderFactory.init");
38 | File configFile = (File)context.get("configFile");
39 | if( configFile == null ) throw new RuntimeException("Could not find config file in context. Should have been added earlier");
40 | log.debug( "configFile: " + configFile.getAbsolutePath());
41 | file = configFile.getParentFile();
42 | context.put("rootFolder",file);
43 | File propsFile = new File(file, "environment.properties");
44 | loadEnvironmentProperties(context,propsFile);
45 | }
46 |
47 | private void loadEnvironmentProperties(RootContext context, final File propsFile) throws RuntimeException {
48 | log.debug("loadEnvironmentProperties");
49 | if( !propsFile.exists() ) {
50 | log.warn("properties file does not exist: " + propsFile.getAbsolutePath());
51 | return ;
52 | }
53 | final Properties props = new Properties();
54 | FileInputStream fin = null;
55 | try {
56 | fin = new FileInputStream(propsFile);
57 | props.load(fin);
58 | } catch (FileNotFoundException ex) {
59 | throw new RuntimeException(ex);
60 | } catch (Exception ex) {
61 | throw new RuntimeException(ex);
62 | } finally {
63 | close(fin);
64 | }
65 | for( String s : props.stringPropertyNames() ) {
66 | String v = props.getProperty(s);
67 | // debug("Registering property: " + s + " = " + v );
68 | context.put(s, v);
69 | }
70 | }
71 |
72 | private void close(InputStream in) {
73 | if( in == null ) return ;
74 | try {
75 | in.close();
76 | } catch (IOException ex) {
77 | log.warn("exception closing stream",ex);
78 | }
79 | }
80 |
81 |
82 | public void destroy() {
83 | }
84 |
85 | public void onRemove(File item) {
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/Dependent.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | public interface Dependent {
4 | public Class[] getDependencies();
5 | }
6 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/Executable.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | public interface Executable {
4 | public T execute( Context context );
5 | }
6 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/Executable2.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | public interface Executable2 {
4 | public void execute( Context context );
5 | }
6 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/Factory.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | public interface Factory extends RemovalCallback {
4 | public Class[] keyClasses();
5 | public String[] keyIds();
6 | public Registration insert(RootContext context, Context requestContext);
7 | public void init( RootContext context);
8 | void destroy();
9 | }
10 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/ListFactory.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | *
8 | */
9 | public class ListFactory implements Factory{
10 |
11 | final String[] ids;
12 | final List beanLocators;
13 |
14 | public ListFactory(String id, List beanLocators) {
15 | ids = new String[] {id};
16 | this.beanLocators = beanLocators;
17 | }
18 |
19 | public Class[] keyClasses() {
20 | return null; // only key by id
21 | }
22 |
23 | public String[] keyIds() {
24 | throw new UnsupportedOperationException("Not supported yet.");
25 | }
26 |
27 | public Registration insert(RootContext context, Context requestContext) {
28 | List list = new ArrayList();
29 | for( BeanLocator bl : beanLocators ) {
30 | Object o = bl.locateBean(requestContext);
31 | list.add(o);
32 | }
33 | Registration reg = new Registration(list, null, context);
34 | return reg;
35 | }
36 |
37 | public void init(RootContext context) {
38 |
39 | }
40 |
41 | public void destroy() {
42 |
43 | }
44 |
45 | public void onRemove(List item) {
46 |
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/PostgresUtils.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | import com.ettrema.context.RequestContext;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.io.OutputStream;
7 | import java.sql.Connection;
8 | import java.sql.PreparedStatement;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 | import java.util.List;
12 |
13 |
14 | /**
15 | *
16 | * @author brad
17 | */
18 | public class PostgresUtils {
19 |
20 |
21 | public static Connection con() {
22 | return requestContext().get( Connection.class );
23 | }
24 |
25 | public static RequestContext requestContext() {
26 | return RequestContext.getCurrent();
27 | }
28 |
29 | public static void close( InputStream in ) {
30 | if( in == null ) return;
31 | try {
32 | in.close();
33 | } catch( IOException ex ) {
34 | throw new RuntimeException( ex );
35 | }
36 | }
37 |
38 | public static void close( OutputStream out ) {
39 | if( out == null ) return;
40 |
41 | try {
42 | out.close();
43 | } catch( IOException ex ) {
44 | throw new RuntimeException( ex );
45 | }
46 | }
47 |
48 | public static void close( ResultSet rs ) {
49 | if( rs == null ) {
50 | return;
51 | }
52 | try {
53 | rs.close();
54 | } catch( SQLException ex ) {
55 | throw new RuntimeException( ex );
56 | }
57 | }
58 |
59 |
60 | static boolean isEmpty( List roots ) {
61 | return roots == null || roots.size()==0;
62 | }
63 |
64 | public static void close( PreparedStatement stmt ) {
65 | if( stmt == null ) {
66 | return ;
67 | } else {
68 | try {
69 | stmt.close();
70 | } catch( SQLException ex ) {
71 |
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/ReferenceBeanLocator.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | /**
4 | *
5 | */
6 | public class ReferenceBeanLocator implements BeanLocator {
7 | final String id;
8 |
9 | public ReferenceBeanLocator(String id) {
10 | this.id = id;
11 | }
12 |
13 | public Object locateBean(Context context) {
14 | return context.get(id);
15 | }
16 |
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/Registration.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | import java.lang.ref.WeakReference;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 | import java.util.Stack;
7 |
8 | public class Registration {
9 | public final T item;
10 | public final RemovalCallback callBack;
11 | public List dependents;
12 | private List keyIds;
13 | private List keyClasses;
14 | private boolean removing;
15 | private WeakReference refParent;
16 |
17 | public Registration(T o,RemovalCallback callBack, Context parent ) {
18 | item = o;
19 | this.callBack = callBack;
20 | refParent = new WeakReference(parent);
21 | }
22 |
23 | private Context context() {
24 | return refParent.get();
25 | }
26 |
27 | public void addDependent(Registration rm) {
28 | if( dependents == null ) dependents = new Stack();
29 | dependents.add( 0,rm );
30 | }
31 |
32 | public void addKey(String id) {
33 | if( keyIds == null ) keyIds = new ArrayList();
34 | keyIds.add(id);
35 | }
36 |
37 | public void addKey(Class c ) {
38 | if( keyClasses == null ) keyClasses = new ArrayList();
39 | keyClasses.add(c);
40 | }
41 |
42 | public boolean contains(Class c) {
43 | if( keyClasses == null ) return false;
44 | return keyClasses.contains(c);
45 | }
46 |
47 | public void remove() {
48 | if( removing ) return;
49 | removing = true;
50 |
51 | // Do dependents (ie child objects first)
52 | if( dependents != null ) {
53 | for( Registration rm : dependents) {
54 | rm.remove();
55 | }
56 | dependents = null;
57 | }
58 |
59 |
60 | if( callBack != null ) {
61 | callBack.onRemove(item);
62 | }
63 | if( keyIds != null ) {
64 | for( String id : keyIds ) {
65 | context().itemByName.remove(id);
66 | }
67 | keyIds = null;
68 | }
69 | if( keyClasses != null ) {
70 | for( Class c : keyClasses ) {
71 | context().itemByClass.remove(c);
72 | }
73 | keyClasses = null;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/RemovalCallback.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | public interface RemovalCallback {
4 | public void onRemove( T item );
5 | }
6 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/RootContextLocator.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | /**
4 | *
5 | * @author brad
6 | */
7 | public class RootContextLocator {
8 | private RootContext rootContext;
9 |
10 | public RootContext getRootContext() {
11 | return rootContext;
12 | }
13 |
14 | public void setRootContext( RootContext rootContext ) {
15 | this.rootContext = rootContext;
16 | }
17 |
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/SimpleBeanLocator.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | /**
4 | *
5 | */
6 | public class SimpleBeanLocator implements BeanLocator{
7 |
8 | final Object bean;
9 |
10 | public SimpleBeanLocator(Object bean) {
11 | this.bean = bean;
12 | }
13 |
14 |
15 | public Object locateBean(Context context) {
16 | return bean;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/SingletonFactory.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 |
11 | /**
12 | *
13 | * @author brad
14 | */
15 | public class SingletonFactory implements Factory{
16 |
17 | private static final Logger log = LoggerFactory.getLogger(SingletonFactory.class);
18 |
19 | private Object bean;
20 | private Class[] keyClasses;
21 |
22 | @Override
23 | public Class[] keyClasses() {
24 | return keyClasses;
25 | }
26 |
27 | @Override
28 | public String[] keyIds() {
29 | return null;
30 | }
31 |
32 | @Override
33 | public Registration insert(RootContext context, Context requestContext) {
34 | return context.put(bean);
35 | }
36 |
37 | @Override
38 | public void init(RootContext context) {
39 |
40 | }
41 |
42 | @Override
43 | public void destroy() {
44 | if( bean instanceof Closeable) {
45 | log.warn( "closing: " + bean.getClass());
46 | Closeable c = (Closeable) bean;
47 | try {
48 | c.close();
49 | } catch( IOException ex ) {
50 | log.error("Exception closing: " + bean.getClass(), ex);
51 | }
52 | } else {
53 | log.warn( "not closing: " + bean.getClass());
54 | }
55 | }
56 |
57 | @Override
58 | public void onRemove(Object item) {
59 |
60 | }
61 |
62 | public String getBeanClass() {
63 | return bean.getClass().getCanonicalName();
64 | }
65 |
66 | public String getKeyClasses() {
67 | String s = "";
68 | for( Class c : keyClasses ) {
69 | s = s + c.getCanonicalName() + ",";
70 | }
71 | return s;
72 | }
73 |
74 | public void setBean( Object bean ) {
75 | this.bean = bean;
76 | List list = new ArrayList();
77 | list.add( bean.getClass());
78 | log.debug("setBean: " + bean.getClass().getCanonicalName());
79 | for(Class c : this.bean.getClass().getInterfaces() ) {
80 | list.add( c );
81 | log.debug(" - add interface: " + c.getCanonicalName());
82 | }
83 | Class superClass = this.bean.getClass().getSuperclass();
84 | while( superClass != null ) {
85 | list.add(superClass);
86 | superClass = superClass.getSuperclass();
87 | }
88 |
89 | this.keyClasses = new Class[list.size()];
90 | list.toArray( keyClasses );
91 | }
92 |
93 | public Object getBean() {
94 | return bean;
95 | }
96 |
97 | @Override
98 | public String toString() {
99 | if( bean != null ) {
100 | return "SingletonFactory(" + bean.getClass() + ")";
101 | } else {
102 | return super.toString();
103 | }
104 | }
105 |
106 |
107 |
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/SpringContextFactory.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | import java.io.File;
4 | import org.springframework.context.ApplicationContext;
5 | import org.springframework.context.support.FileSystemXmlApplicationContext;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 |
10 | /**
11 | *
12 | */
13 | public class SpringContextFactory implements Factory{
14 |
15 | private static final Logger log = LoggerFactory.getLogger(CtxRootFolderFactory.class);
16 |
17 | private String appContext;
18 | private ApplicationContext springContext;
19 | Class[] classes = new Class[]{ApplicationContext.class};
20 |
21 | @Override
22 | public Class[] keyClasses() {
23 | return classes;
24 | }
25 |
26 | @Override
27 | public String[] keyIds() {
28 | return null;
29 | }
30 |
31 | @Override
32 | public Registration insert(RootContext context, Context requestContext) {
33 | Registration reg = context.put(springContext, this);
34 | return reg;
35 | }
36 |
37 | @Override
38 | public void init(RootContext context) {
39 | log.debug("app context is configured at: " + appContext);
40 | File fXml;
41 | if( appContext.startsWith("/") || appContext.contains(":")) {
42 | log.debug("app context path looks like an absolute path");
43 | fXml = new File(appContext);
44 | } else {
45 | log.debug("app context path looks relative, so resolving from rootFolder");
46 | File root = context.get("rootFolder");
47 | fXml = new File(root,appContext);
48 | }
49 | log.debug("absolute path: " + fXml.getAbsolutePath());
50 | springContext = new FileSystemXmlApplicationContext(appContext);
51 | }
52 |
53 | @Override
54 | public void destroy() {
55 | springContext = null;
56 | }
57 |
58 | @Override
59 | public void onRemove(ApplicationContext item) {
60 |
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/SpringFactory.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import org.springframework.context.ApplicationContext;
6 |
7 | /**
8 | *
9 | */
10 | public class SpringFactory implements Factory {
11 | private Class[] classes;
12 | private String id;
13 |
14 | public Class[] keyClasses() {
15 | return classes;
16 | }
17 |
18 | public String[] keyIds() {
19 | return new String[] {id};
20 | }
21 |
22 | public Registration insert(RootContext context, Context requestContext) {
23 | ApplicationContext appContext = requestContext.get(ApplicationContext.class);
24 | Object o = appContext.getBean(id);
25 | return context.put(o);
26 | }
27 |
28 | public void init(RootContext context) {
29 | }
30 |
31 | public void destroy() {
32 | }
33 |
34 | public void onRemove(Object item) {
35 | }
36 |
37 |
38 | /**
39 | * @return the classes
40 | */
41 | public String getClasses() {
42 | String s = "";
43 | for(Class clazz : classes ) {
44 | s = s +"," + clazz.getCanonicalName();
45 | }
46 | return s;
47 | }
48 |
49 | /**
50 | * @param classes the classes to set
51 | */
52 | public void setClasses(String classes) {
53 | String[] classNames = classes.split(",");
54 | List list = new ArrayList();
55 | for( String className : classNames ) {
56 | Class clazz;
57 | try {
58 | clazz = Class.forName(className);
59 | } catch (ClassNotFoundException ex) {
60 | throw new RuntimeException(className, ex);
61 | }
62 | list.add(clazz);
63 | }
64 | this.classes = new Class[list.size()];
65 | list.toArray(this.classes);
66 | }
67 |
68 | /**
69 | * @return the ids
70 | */
71 | public String getId() {
72 | return id;
73 | }
74 |
75 | /**
76 | * @param ids the ids to set
77 | */
78 | public void setIds(String id) {
79 | this.id = id;
80 | }
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/context/date/CtxDateFormatFactory.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.context.date;
2 |
3 | import com.ettrema.context.Context;
4 | import com.ettrema.context.Factory;
5 | import com.ettrema.context.Registration;
6 | import com.ettrema.context.RootContext;
7 | import java.text.DateFormat;
8 |
9 | public class CtxDateFormatFactory implements Factory {
10 |
11 | public static Class[] classes = {DateFormat.class};
12 |
13 | public CtxDateFormatFactory() {
14 | }
15 |
16 | public Class[] keyClasses() {
17 | return classes;
18 | }
19 |
20 | public String[] keyIds() {
21 | return null;
22 | }
23 |
24 | public Registration insert(RootContext context, Context requestContext) {
25 | DateFormat d = DateFormat.getDateInstance(DateFormat.SHORT);
26 | Registration reg = requestContext.put(d,this);
27 | return reg;
28 | }
29 |
30 | public void init(RootContext context) {
31 | }
32 |
33 | public void destroy() {
34 | }
35 |
36 | public void onRemove(DateFormat item) {
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/TableCreatorService.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db;
2 |
3 | import com.ettrema.db.dialects.Dialect;
4 | import com.ettrema.common.Service;
5 | import com.ettrema.context.Context;
6 | import com.ettrema.context.Executable2;
7 | import com.ettrema.context.RootContext;
8 | import com.ettrema.context.PostgresUtils;
9 | import java.sql.Connection;
10 | import java.sql.SQLException;
11 | import java.util.List;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 | /**
16 | *
17 | * @author brad
18 | */
19 | public class TableCreatorService implements Service {
20 |
21 | private static final Logger log = LoggerFactory.getLogger(TableCreatorService.class);
22 | private final RootContext rootContext;
23 | private final Dialect dialect;
24 | protected List definitionSources;
25 |
26 | public TableCreatorService(RootContext rootContext, List definitionSources, Dialect dialect) {
27 | this.rootContext = rootContext;
28 | this.definitionSources = definitionSources;
29 | this.dialect = dialect;
30 | }
31 |
32 | @Override
33 | public void start() {
34 | rootContext.execute(new Executable2() {
35 |
36 | @Override
37 | public void execute(Context context) {
38 | log.warn("doing check and create of tables. Tables which do not exist will be created");
39 | try {
40 | Connection con = PostgresUtils.con();
41 | processTableDefinitions(con);
42 | } catch (Exception e) {
43 | log.error("Exception checking table definitions, will continue anyway...", e);
44 | }
45 | }
46 | });
47 | }
48 |
49 | public void processTableDefinitions(Connection con) {
50 | for (TableDefinitionSource source : definitionSources) {
51 | for (Table t : source.getTableDefinitions()) {
52 | checkAndCreate(t, con, source);
53 | }
54 | }
55 |
56 | }
57 |
58 | private void checkAndCreate(Table table, Connection con, TableDefinitionSource source) {
59 | if (!dialect.tableExists(table.tableName, con)) {
60 | log.warn("create table: " + table.tableName);
61 | dialect.createTable(table, con);
62 | source.onCreate(table, con);
63 | commit(con);
64 | }
65 | }
66 |
67 | private void commit(Connection con) {
68 | try {
69 | con.commit();
70 | } catch (SQLException ex) {
71 | throw new RuntimeException(ex);
72 | }
73 | }
74 |
75 | @Override
76 | public void stop() {
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/TableDefinitionSource.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db;
2 |
3 | import java.sql.Connection;
4 | import java.util.List;
5 |
6 | /**
7 | *
8 | * @author brad
9 | */
10 | public interface TableDefinitionSource {
11 | List extends Table> getTableDefinitions();
12 |
13 | void onCreate(Table t, Connection con);
14 | }
15 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/UseConnection.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db;
2 |
3 | import com.bradmcevoy.utils.With;
4 | import java.sql.Connection;
5 | import java.sql.PreparedStatement;
6 | import java.sql.ResultSet;
7 | import java.sql.SQLException;
8 | import javax.sql.DataSource;
9 |
10 | /**
11 | *
12 | * @author brad
13 | */
14 | public class UseConnection {
15 |
16 |
17 |
18 | private final DataSource ds;
19 |
20 | public UseConnection( DataSource ds ) {
21 | this.ds = ds;
22 | }
23 |
24 | public O use( With with ) {
25 | Connection con = null;
26 | try {
27 | con = ds.getConnection();
28 | O o = with.use( con );
29 | commit( con );
30 | return o;
31 | } catch( Exception ex ) {
32 | rollback(con);
33 | throw new RuntimeException( ex );
34 | } finally {
35 | close( con );
36 | }
37 | }
38 |
39 | private void commit(Connection con) throws SQLException {
40 | con.commit();
41 | }
42 |
43 | private void rollback( Connection con ) {
44 | if( con != null ) {
45 | try {
46 | con.rollback();
47 | } catch( SQLException ex ) {
48 |
49 | }
50 | }
51 | }
52 |
53 | public static void close( Connection con ) {
54 | if( con != null ) {
55 | try {
56 | con.close();
57 | } catch( SQLException ex ) {
58 | }
59 | }
60 | }
61 |
62 | public static void close( ResultSet rs ) {
63 | if( rs != null ) {
64 | try {
65 | rs.close();
66 | } catch( SQLException ex ) {
67 | }
68 | }
69 | }
70 |
71 | public static void close( PreparedStatement stmt ) {
72 | if( stmt != null ) {
73 | try {
74 | stmt.close();
75 | } catch( SQLException ex ) {
76 | }
77 | }
78 |
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/dialects/Dialect.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.dialects;
2 |
3 | import com.ettrema.db.Table;
4 | import com.ettrema.db.types.FieldType;
5 | import java.sql.Connection;
6 |
7 | /**
8 | *
9 | * @author brad
10 | */
11 | public interface Dialect {
12 | boolean tableExists(String name, Connection con);
13 |
14 | void createTable( Table table, Connection con );
15 |
16 | String getTypeName(FieldType type);
17 | }
18 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/dialects/H2Dialect.java:
--------------------------------------------------------------------------------
1 |
2 | package com.ettrema.db.dialects;
3 |
4 | import com.ettrema.db.Table;
5 | import com.ettrema.db.types.BinaryType;
6 | import com.ettrema.db.types.FieldType;
7 | import java.sql.Connection;
8 | import java.sql.ResultSet;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | /**
13 | * Mostly the same as postgres, but need to uppercase table names
14 | *
15 | * @author brad
16 | */
17 | public class H2Dialect implements Dialect{
18 |
19 | private static final Logger log = LoggerFactory.getLogger(H2Dialect.class);
20 |
21 |
22 | private String catalog;
23 |
24 | private String schemaPattern;
25 |
26 | @Override
27 | public boolean tableExists( String name, Connection con ) {
28 | try {
29 | // ** make table name uppercase **
30 | ResultSet tables = con.getMetaData().getTables( catalog, schemaPattern, name.toUpperCase(), null );
31 | boolean b = tables.next();
32 | log.warn( "does table exist: " + name + " = " + b);
33 | return b;
34 | } catch(Exception e) {
35 | throw new RuntimeException( "Exception looking for tables: catalog:" + catalog + " schema:" + schemaPattern, e);
36 | }
37 | }
38 |
39 | @Override
40 | public void createTable( Table table, Connection con ) {
41 | table.createTable( con, this );
42 | }
43 |
44 | public String getCatalog() {
45 | return catalog;
46 | }
47 |
48 | public void setCatalog( String catalog ) {
49 | this.catalog = catalog;
50 | }
51 |
52 | public String getSchemaPattern() {
53 | return schemaPattern;
54 | }
55 |
56 | public void setSchemaPattern( String schemaPattern ) {
57 | this.schemaPattern = schemaPattern;
58 | }
59 |
60 | @Override
61 | public String getTypeName( FieldType type ) {
62 | if( type instanceof BinaryType) {
63 | return "bytea";
64 | } else {
65 | return type.toString().toLowerCase();
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/dialects/HqlDialect.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.dialects;
2 |
3 | import com.ettrema.db.Table;
4 | import com.ettrema.db.types.FieldType;
5 | import java.sql.Connection;
6 | import java.sql.ResultSet;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | /**
11 | *
12 | * @author brad
13 | */
14 | public class HqlDialect implements Dialect{
15 |
16 | private static final Logger log = LoggerFactory.getLogger(HqlDialect.class);
17 |
18 |
19 | private String catalog;
20 |
21 | private String schemaPattern;
22 |
23 | @Override
24 | public boolean tableExists( String name, Connection con ) {
25 | try {
26 | ResultSet tables = con.getMetaData().getTables( catalog, schemaPattern, name.toUpperCase(), null );
27 | boolean b = tables.next();
28 | log.warn( "does table exist: " + name + " = " + b);
29 | return b;
30 | } catch(Exception e) {
31 | throw new RuntimeException( "Exception looking for tables: catalog:" + catalog + " schema:" + schemaPattern, e);
32 | }
33 | }
34 |
35 | @Override
36 | public void createTable( Table table, Connection con ) {
37 | table.createTable( con, this );
38 | }
39 |
40 | public String getCatalog() {
41 | return catalog;
42 | }
43 |
44 | public void setCatalog( String catalog ) {
45 | this.catalog = catalog;
46 | }
47 |
48 | public String getSchemaPattern() {
49 | return schemaPattern;
50 | }
51 |
52 | public void setSchemaPattern( String schemaPattern ) {
53 | this.schemaPattern = schemaPattern;
54 | }
55 |
56 | @Override
57 | public String getTypeName( FieldType type ) {
58 | return type.toString().toLowerCase();
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/dialects/PostgresDialect.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.dialects;
2 |
3 | import com.ettrema.db.Table;
4 | import com.ettrema.db.types.BinaryType;
5 | import com.ettrema.db.types.FieldType;
6 | import java.sql.Connection;
7 | import java.sql.ResultSet;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | /**
12 | *
13 | * @author brad
14 | */
15 | public class PostgresDialect implements Dialect {
16 |
17 | private static final Logger log = LoggerFactory.getLogger(PostgresDialect.class);
18 |
19 |
20 | private String catalog;
21 |
22 | private String schemaPattern;
23 |
24 | @Override
25 | public boolean tableExists( String name, Connection con ) {
26 | try {
27 | ResultSet tables = con.getMetaData().getTables( catalog, schemaPattern, name, null );
28 | boolean b = tables.next();
29 | log.warn( "does table exist: " + name + " = " + b);
30 | return b;
31 | } catch(Exception e) {
32 | throw new RuntimeException( "Exception looking for tables: catalog:" + catalog + " schema:" + schemaPattern, e);
33 | }
34 | }
35 |
36 | @Override
37 | public void createTable( Table table, Connection con ) {
38 | table.createTable( con, this );
39 | }
40 |
41 | public String getCatalog() {
42 | return catalog;
43 | }
44 |
45 | public void setCatalog( String catalog ) {
46 | this.catalog = catalog;
47 | }
48 |
49 | public String getSchemaPattern() {
50 | return schemaPattern;
51 | }
52 |
53 | public void setSchemaPattern( String schemaPattern ) {
54 | this.schemaPattern = schemaPattern;
55 | }
56 |
57 | @Override
58 | public String getTypeName( FieldType type ) {
59 | if( type instanceof BinaryType) {
60 | return "bytea";
61 | } else {
62 | return type.toString().toLowerCase();
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/types/BinaryType.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.types;
2 |
3 | import java.io.Serializable;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 |
8 | public class BinaryType implements FieldType, Serializable {
9 |
10 | private static final long serialVersionUID = 1L;
11 |
12 | @Override
13 | public String toString() {
14 | return "binary";
15 | }
16 |
17 | @Override
18 | public byte[] get(String name, ResultSet rs) throws SQLException {
19 | return rs.getBytes(name);
20 | }
21 |
22 | @Override
23 | public void set(PreparedStatement stmt, int index, byte[] value) throws SQLException {
24 | if (value == null) {
25 | stmt.setNull(index, java.sql.Types.VARBINARY);
26 | } else {
27 | stmt.setBytes(index, value);
28 | }
29 | }
30 |
31 | @Override
32 | public byte[] parse(Object v) {
33 | if (v instanceof byte[]) {
34 | return (byte[]) v;
35 | } else {
36 | throw new RuntimeException("Cant parse type of: " + v.getClass());
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/types/CharacterType.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.types;
2 |
3 | import java.io.Serializable;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 | import java.sql.Types;
8 |
9 | public class CharacterType implements FieldType, Serializable {
10 |
11 | private static final long serialVersionUID = 1L;
12 | private final int length;
13 |
14 | public CharacterType(int length) {
15 | this.length = length;
16 | }
17 |
18 | public int getLength() {
19 | return length;
20 | }
21 |
22 | @Override
23 | public String toString() {
24 | return "character(" + length + ")";
25 | }
26 |
27 | @Override
28 | public String get(String name, ResultSet rs) throws SQLException {
29 | return rs.getString(name);
30 | }
31 |
32 | @Override
33 | public void set(PreparedStatement stmt, int index, String value) throws SQLException {
34 | if (value == null) {
35 | stmt.setNull(index, Types.VARCHAR);
36 | } else {
37 | stmt.setString(index, value);
38 | }
39 | }
40 |
41 | @Override
42 | public String parse(Object v) {
43 | if (v instanceof String) {
44 | return (String) v;
45 | } else {
46 | return v.toString();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/types/CharacterVaryingType.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.types;
2 |
3 | import java.io.Serializable;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 | import java.sql.Types;
8 |
9 | public class CharacterVaryingType implements FieldType, Serializable {
10 |
11 | private static final long serialVersionUID = 1L;
12 |
13 | @Override
14 | public String toString() {
15 | return "character varying";
16 | }
17 |
18 | @Override
19 | public String get(String name, ResultSet rs) throws SQLException {
20 | return rs.getString(name);
21 | }
22 |
23 | @Override
24 | public void set(PreparedStatement stmt, int index, String value) throws SQLException {
25 | if (value == null) {
26 | stmt.setNull(index, Types.VARCHAR);
27 | } else {
28 | stmt.setString(index, value);
29 | }
30 | }
31 |
32 | @Override
33 | public String parse(Object v) {
34 | if (v instanceof String) {
35 | return (String) v;
36 | } else {
37 | return v.toString();
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/types/FieldType.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.types;
2 |
3 | import java.sql.PreparedStatement;
4 | import java.sql.ResultSet;
5 | import java.sql.SQLException;
6 |
7 | public interface FieldType {
8 |
9 | T get(String name, ResultSet rs) throws SQLException;
10 |
11 | void set(PreparedStatement stmt, int index, T value) throws SQLException;
12 |
13 | /**
14 | * Attempt to parse whatever object is given to the actual value. Should handle
15 | * strings and similar types. Eg Integer should handle long, date should
16 | * handle timestamp, etc
17 | *
18 | * @param v
19 | * @return
20 | */
21 | T parse(Object v);
22 | }
23 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/types/FieldTypes.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.types;
2 |
3 | /**
4 | *
5 | * @author brad
6 | */
7 | public class FieldTypes {
8 |
9 | public final static CharacterVaryingType CHARACTER_VARYING = new CharacterVaryingType();
10 | public final static BinaryType BINARY = new BinaryType();
11 | public final static IntegerType INTEGER = new IntegerType();
12 | public final static LongType LONG = new LongType();
13 | public final static TimestampType TIMESTAMP = new TimestampType();
14 | public final static Float8Type FLOAT8 = new Float8Type();
15 | public final static FieldType[] allTypes = {
16 | CHARACTER_VARYING,
17 | BINARY,
18 | INTEGER,
19 | LONG,
20 | TIMESTAMP,
21 | FLOAT8
22 | };
23 |
24 | public static CharacterType character(int length) {
25 | return new CharacterType(length);
26 | }
27 |
28 | public static FieldType fromName(String name) {
29 | for (FieldType type : allTypes) {
30 | if (type.toString().equals(name)) {
31 | return type;
32 | }
33 | }
34 | return null;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/types/Float8Type.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.types;
2 |
3 | import java.io.Serializable;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 | import java.sql.Types;
8 |
9 | /**
10 | *
11 | * @author brad
12 | */
13 | public class Float8Type implements FieldType, Serializable {
14 |
15 | private static final long serialVersionUID = 1L;
16 |
17 | @Override
18 | public String toString() {
19 | return "double precision";
20 | }
21 |
22 | @Override
23 | public Float get(String name, ResultSet rs) throws SQLException {
24 | return rs.getFloat(name);
25 | }
26 |
27 | @Override
28 | public void set(PreparedStatement stmt, int index, Float value) throws SQLException {
29 | if (value == null) {
30 | stmt.setNull(index, Types.REAL);
31 | } else {
32 | stmt.setFloat(index, value);
33 | }
34 |
35 | }
36 |
37 | @Override
38 | public Float parse(Object v) {
39 | if (v instanceof Float) {
40 | return (Float) v;
41 | } else if (v instanceof Double) {
42 | Double d = (Double) v;
43 | return d.floatValue();
44 | } else if (v instanceof String) {
45 | String s = (String) v;
46 | return Float.parseFloat(s);
47 | } else {
48 | throw new RuntimeException("Cant convert type: " + v.getClass());
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/types/IntegerType.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.types;
2 |
3 | import java.io.Serializable;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 | import java.sql.Types;
8 |
9 | public class IntegerType implements FieldType, Serializable {
10 |
11 | private static final long serialVersionUID = 1L;
12 |
13 | @Override
14 | public String toString() {
15 | return "integer";
16 | }
17 |
18 | @Override
19 | public Integer get(String name, ResultSet rs) throws SQLException {
20 | return rs.getInt(name);
21 | }
22 |
23 | @Override
24 | public void set(PreparedStatement stmt, int index, Integer value) throws SQLException {
25 | if (value == null) {
26 | stmt.setNull(index, Types.INTEGER);
27 | } else {
28 | stmt.setInt(index, value);
29 | }
30 |
31 | }
32 |
33 | @Override
34 | public Integer parse(Object v) {
35 | if (v instanceof Integer) {
36 | return (Integer) v;
37 | } else if (v instanceof Long) {
38 | Long d = (Long) v;
39 | return d.intValue();
40 | } else if (v instanceof String) {
41 | String s = (String) v;
42 | return Integer.parseInt(s);
43 | } else {
44 | throw new RuntimeException("Cant convert type: " + v.getClass());
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/types/LongType.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.types;
2 |
3 | import java.io.Serializable;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 |
8 | /**
9 | *
10 | * @author brad
11 | */
12 | public class LongType implements FieldType, Serializable {
13 |
14 | private static final long serialVersionUID = 1L;
15 |
16 | @Override
17 | public String toString() {
18 | return "long";
19 | }
20 |
21 | @Override
22 | public Long get(String name, ResultSet rs) throws SQLException {
23 | Object oLong = rs.getObject(name);
24 | if( oLong == null ) {
25 | return null;
26 | } else {
27 | return (Long)oLong;
28 | }
29 | }
30 |
31 | @Override
32 | public void set(PreparedStatement stmt, int index, Long value) throws SQLException {
33 | if (value == null) {
34 | stmt.setNull(index, java.sql.Types.BIGINT);
35 | } else {
36 | stmt.setLong(index, value);
37 | }
38 | }
39 |
40 | @Override
41 | public Long parse(Object v) {
42 | if (v instanceof Long) {
43 | return (Long) v;
44 | } else if (v instanceof Integer) {
45 | Integer d = (Integer) v;
46 | return d.longValue();
47 | } else if (v instanceof String) {
48 | String s = (String) v;
49 | return Long.parseLong(s);
50 | } else {
51 | throw new RuntimeException("Cant convert type: " + v.getClass());
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/com/ettrema/db/types/TimestampType.java:
--------------------------------------------------------------------------------
1 | package com.ettrema.db.types;
2 |
3 | import java.io.Serializable;
4 | import java.sql.PreparedStatement;
5 | import java.sql.ResultSet;
6 | import java.sql.SQLException;
7 | import java.sql.Timestamp;
8 | import java.sql.Types;
9 |
10 | /**
11 | *
12 | * @author brad
13 | */
14 | public class TimestampType implements FieldType, Serializable {
15 |
16 | private static final long serialVersionUID = 1L;
17 |
18 | @Override
19 | public String toString() {
20 | return "timestamp";
21 | }
22 |
23 | @Override
24 | public java.sql.Timestamp get(String name, ResultSet rs) throws SQLException {
25 | return rs.getTimestamp(name);
26 | }
27 |
28 | @Override
29 | public void set(PreparedStatement stmt, int index, Timestamp value) throws SQLException {
30 | if (value == null) {
31 | stmt.setNull(index, Types.TIMESTAMP);
32 | } else {
33 | stmt.setTimestamp(index, value);
34 | }
35 | }
36 |
37 | @Override
38 | public java.sql.Timestamp parse(Object v) {
39 | if (v instanceof java.sql.Timestamp) {
40 | return (java.sql.Timestamp) v;
41 | } else if (v instanceof String) {
42 | String s = (String) v;
43 | return java.sql.Timestamp.valueOf(s);
44 | } else {
45 | throw new RuntimeException("Cant convert type: " + v.getClass());
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/Archiver.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import io.milton.common.FileUtils;
4 | import java.io.File;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | /**
9 | * For removing old versions of local files when they're updated.
10 | *
11 | * This bit is quite sensitive, we really can't afford to eat anyone's files!
12 | *
13 | * So this implementation is very defensive, it never deletes files, just moves
14 | * them into a versions folder
15 | *
16 | * @author brad
17 | */
18 | public class Archiver {
19 |
20 | private static final Logger log = LoggerFactory.getLogger(Archiver.class);
21 |
22 | public Archiver() {
23 | }
24 |
25 |
26 |
27 | public void archive(File f) {
28 | File versions = getVersionsDir(f);
29 | File dest = new File(versions, f.getName());
30 | String name = FileUtils.incrementFileName(dest.getName(), true);
31 | while(dest.exists()) {
32 | name = FileUtils.incrementFileName(name, false);
33 | dest = new File(versions, name);
34 | }
35 | if( !f.renameTo(dest) ) {
36 | throw new RuntimeException("Couldnt archive old file: " + f.getAbsolutePath() + " to: " + dest.getAbsolutePath() );
37 | }
38 | }
39 |
40 | private File getVersionsDir(File contentFile) {
41 | File hiddenDir = new File(contentFile.getParent(), ".spliffy");
42 | if (!hiddenDir.exists()) {
43 | log.info("getVersionsDir: Creating missing hidden dir", hiddenDir.getAbsolutePath());
44 | if (!hiddenDir.mkdirs()) {
45 | throw new RuntimeException("Couldnt create directory: " + hiddenDir.getAbsolutePath());
46 | }
47 | }
48 | File versionsDir = new File(hiddenDir, "versions");
49 | if( !versionsDir.exists()) {
50 | log.info("getVersionsDir: Creating missing versions dir", versionsDir.getAbsolutePath());
51 | if(!versionsDir.mkdirs() ) {
52 | throw new RuntimeException("Couldnt create directory for old versions: " + versionsDir.getAbsolutePath());
53 | }
54 | }
55 | return versionsDir;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/DbInitialiser.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import com.ettrema.db.UseConnection;
4 | import com.ettrema.db.dialects.Dialect;
5 | import com.ettrema.db.dialects.HqlDialect;
6 | import java.io.File;
7 | import javax.sql.DataSource;
8 | import org.apache.commons.dbcp.ConnectionFactory;
9 | import org.apache.commons.dbcp.DriverManagerConnectionFactory;
10 | import org.apache.commons.dbcp.PoolableConnectionFactory;
11 | import org.apache.commons.dbcp.PoolingDataSource;
12 | import org.apache.commons.pool.impl.GenericObjectPool;
13 |
14 | /**
15 | * Just hard codes initialisation of an embedded H2 instance
16 | *
17 | *
18 | * @author brad
19 | */
20 | public class DbInitialiser {
21 |
22 | private final DataSource ds;
23 | private final UseConnection useConnection;
24 | private final Dialect dialect;
25 |
26 | public DbInitialiser(File dbFile) {
27 | String url = "jdbc:h2:" + dbFile.getAbsolutePath();
28 |
29 | GenericObjectPool connectionPool = new GenericObjectPool( null );
30 | ConnectionFactory connectionFactory = new DriverManagerConnectionFactory( url, "sa", "sa" );
31 | PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory( connectionFactory, connectionPool, null, null, false, true );
32 | ds = new PoolingDataSource( connectionPool );
33 |
34 | this.useConnection = new UseConnection( ds );
35 |
36 | dialect = new HqlDialect();
37 | }
38 |
39 | public UseConnection getUseConnection() {
40 | return useConnection;
41 | }
42 |
43 | public Dialect getDialect() {
44 | return dialect;
45 | }
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/DeltaListener.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import io.milton.common.Path;
4 | import java.io.IOException;
5 | import org.hashsplit4j.triplets.ITriplet;
6 |
7 | /**
8 | * A "delta" here refers to some difference between the client and server
9 | * file systems.
10 | *
11 | *
12 | * @author brad
13 | */
14 | public interface DeltaListener {
15 |
16 |
17 | void onLocalDeletion(Path path, ITriplet remoteTriplet) throws IOException;
18 |
19 | void onLocalChange(ITriplet localTriplet, Path path, ITriplet remoteTriplet) throws IOException;
20 |
21 | void onRemoteChange(ITriplet remoteTriplet, ITriplet localTriplet, Path path) throws IOException;
22 |
23 | void onRemoteDelete(ITriplet localTriplet, Path path) throws IOException;
24 |
25 | void onTreeConflict(ITriplet remoteTriplet, ITriplet localTriplet, Path path) throws IOException;
26 |
27 | void onFileConflict(ITriplet remoteTriplet, ITriplet localTriplet, Path path) throws IOException;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/HttpUtils.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import io.milton.common.Path;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.io.OutputStream;
7 | import org.apache.commons.io.IOUtils;
8 | import org.apache.http.HttpEntity;
9 | import org.apache.http.HttpResponse;
10 | import org.apache.http.client.methods.HttpUriRequest;
11 |
12 | /**
13 | *
14 | * @author brad
15 | */
16 | public class HttpUtils {
17 |
18 |
19 | /**
20 | * Takes an unencoded local path (eg "/my docs") and turns it into a
21 | * percentage encoded path (eg "/my%20docs"), with the encoded rootPath
22 | * added to the front
23 | *
24 | * @param path
25 | * @return
26 | */
27 | public static String toHref(Path basePath, Path unencodedPath) {
28 | Path p = basePath;
29 | for (String name : unencodedPath.getParts()) {
30 | p = p.child(io.milton.common.Utils.percentEncode(name));
31 | }
32 | return p.toString();
33 | }
34 |
35 | public static int executeHttpWithStatus(org.apache.http.client.HttpClient client, HttpUriRequest m, OutputStream out) throws IOException {
36 | HttpResponse resp = client.execute(m);
37 | HttpEntity entity = resp.getEntity();
38 | if (entity != null) {
39 | InputStream in = null;
40 | try {
41 | in = entity.getContent();
42 | if (out != null) {
43 | IOUtils.copy(in, out);
44 | }
45 | } finally {
46 | IOUtils.closeQuietly(in);
47 | }
48 | }
49 | return resp.getStatusLine().getStatusCode();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/MemoryHashCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 McEvoy Software Ltd.
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | * You should have received a copy of the GNU General Public License
13 | * along with this program. If not, see .
14 | */
15 | package io.milton.sync;
16 |
17 | import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
18 | import java.util.concurrent.ConcurrentMap;
19 | import org.hashsplit4j.api.HashCache;
20 |
21 | /**
22 | * Uses ConcurrentLinkedHashMap to keep a LRU cache of hashes
23 | *
24 | * @author brad
25 | */
26 | public class MemoryHashCache implements HashCache {
27 |
28 | private final ConcurrentMap cache;
29 |
30 | public MemoryHashCache() {
31 | cache = new ConcurrentLinkedHashMap.Builder()
32 | .maximumWeightedCapacity(5000)
33 | .initialCapacity(2000)
34 | .build();
35 | }
36 |
37 | @Override
38 | public boolean hasHash(String key) {
39 | return cache.containsKey(key);
40 | }
41 |
42 | @Override
43 | public void setHash(String key) {
44 | cache.put(key, key);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/MinimalPutsBlobStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import org.hashsplit4j.api.BlobStore;
4 |
5 | /**
6 | *
7 | * @author brad
8 | */
9 |
10 |
11 | public class MinimalPutsBlobStore implements BlobStore{
12 |
13 | private final BlobStore wrapped;
14 |
15 | public MinimalPutsBlobStore(BlobStore wrapped) {
16 | this.wrapped = wrapped;
17 | }
18 |
19 |
20 |
21 | @Override
22 | public void setBlob(String hash, byte[] bytes) {
23 | if( !wrapped.hasBlob(hash)) {
24 | wrapped.setBlob(hash, bytes);
25 | }
26 | }
27 |
28 | @Override
29 | public byte[] getBlob(String string) {
30 | if( wrapped.hasBlob(string)) {
31 | return wrapped.getBlob(string);
32 | }
33 | return null;
34 | }
35 |
36 | @Override
37 | public boolean hasBlob(String string) {
38 | return wrapped.hasBlob(string);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/MinimalPutsHashStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import java.util.List;
4 | import org.hashsplit4j.api.Fanout;
5 | import org.hashsplit4j.api.HashStore;
6 |
7 | /**
8 | *
9 | * @author brad
10 | */
11 |
12 |
13 | public class MinimalPutsHashStore implements HashStore{
14 |
15 | private final HashStore wrapped;
16 |
17 | public MinimalPutsHashStore(HashStore wrapped) {
18 | this.wrapped = wrapped;
19 | }
20 |
21 |
22 |
23 | @Override
24 | public void setChunkFanout(String string, List list, long l) {
25 | if( !wrapped.hasChunk(string)) {
26 | wrapped.setChunkFanout(string, list, l);
27 | }
28 | }
29 |
30 | @Override
31 | public void setFileFanout(String string, List list, long l) {
32 | if( !wrapped.hasFile(string)) {
33 | wrapped.setFileFanout(string, list, l);
34 | }
35 | }
36 |
37 | @Override
38 | public Fanout getFileFanout(String string) {
39 | if( wrapped.hasFile(string)) {
40 | return wrapped.getFileFanout(string);
41 | }
42 | return null;
43 | }
44 |
45 | @Override
46 | public Fanout getChunkFanout(String string) {
47 | if( wrapped.hasChunk(string)) {
48 | return wrapped.getChunkFanout(string);
49 | }
50 | return null;
51 | }
52 |
53 | @Override
54 | public boolean hasChunk(String string) {
55 | return wrapped.hasChunk(string);
56 | }
57 |
58 | @Override
59 | public boolean hasFile(String string) {
60 | return wrapped.hasFile(string);
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/SyncJob.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 McEvoy Software Ltd.
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Affero General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | * You should have received a copy of the GNU General Public License
13 | * along with this program. If not, see .
14 | */
15 | package io.milton.sync;
16 |
17 | import java.io.File;
18 | import java.io.IOException;
19 | import java.io.Serializable;
20 |
21 | /**
22 | *
23 | * @author brad
24 | */
25 | public class SyncJob implements Serializable{
26 | private File localDir;
27 | private String remoteAddress;
28 | private String user;
29 | private String pwd;
30 | private boolean monitor;
31 | private boolean localReadonly;
32 |
33 | public SyncJob() {
34 | }
35 |
36 |
37 | public SyncJob(File localDir, String sRemoteAddress, String user, String pwd, boolean monitor, boolean readonlyLocal) {
38 | this.localDir = localDir;
39 | this.remoteAddress = sRemoteAddress;
40 | this.user = user;
41 | this.pwd = pwd;
42 | this.monitor = monitor;
43 | this.localReadonly = readonlyLocal;
44 | try {
45 | if (!localDir.exists()) {
46 | throw new RuntimeException("Sync dir does not exist: " + localDir.getCanonicalPath());
47 | } else if (!localDir.isDirectory()) {
48 | throw new RuntimeException("Sync path is not a directory: " + localDir.getCanonicalPath());
49 | }
50 | } catch (IOException ex) {
51 | throw new RuntimeException(ex);
52 | }
53 | }
54 |
55 | public String getPwd() {
56 | return pwd;
57 | }
58 |
59 | public void setPwd(String pwd) {
60 | this.pwd = pwd;
61 | }
62 |
63 |
64 |
65 | public String getUser() {
66 | return user;
67 | }
68 |
69 | public void setUser(String user) {
70 | this.user = user;
71 | }
72 |
73 |
74 |
75 | public File getLocalDir() {
76 | return localDir;
77 | }
78 |
79 | public void setLocalDir(File localDir) {
80 | this.localDir = localDir;
81 | }
82 |
83 |
84 |
85 | public String getRemoteAddress() {
86 | return remoteAddress;
87 | }
88 |
89 | public void setRemoteAddress(String remoteAddress) {
90 | this.remoteAddress = remoteAddress;
91 | }
92 |
93 |
94 |
95 | public boolean isMonitor() {
96 | return monitor;
97 | }
98 |
99 | public void setMonitor(boolean monitor) {
100 | this.monitor = monitor;
101 | }
102 |
103 |
104 |
105 | public boolean isLocalReadonly() {
106 | return localReadonly;
107 | }
108 |
109 | public void setLocalReadonly(boolean localReadonly) {
110 | this.localReadonly = localReadonly;
111 | }
112 |
113 |
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/SyncStatusStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import io.milton.common.Path;
4 |
5 | /**
6 | * Represents a means of recording what version of a resource was last synced
7 | *
8 | * @author brad
9 | */
10 | public interface SyncStatusStore {
11 |
12 | String findBackedUpHash(Path path);
13 |
14 | void setBackedupHash(Path path, String hash);
15 |
16 | /**
17 | * Called when the syncronisation has removed a file
18 | *
19 | * @param path
20 | */
21 | void clearBackedupHash(Path path);
22 | }
23 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/Utils.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import io.milton.common.Path;
4 | import java.io.File;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 | import org.hashsplit4j.triplets.ITriplet;
9 |
10 | /**
11 | *
12 | * @author brad
13 | */
14 | public class Utils {
15 |
16 | public static boolean ignored(File childFile) {
17 | return ignored(childFile, null);
18 | }
19 |
20 | public static boolean ignored(File childFile, List ignoredPatterns) {
21 | if( childFile.getName().equals(".ksync") ) { // usually ignore resources starting with a dot, but special case for .mil directory
22 | return true;
23 | }
24 | if( ignoredPatterns != null ) {
25 | for( String s : ignoredPatterns) {
26 | if( childFile.getName().equals(s) || childFile.getName().matches(s)) {
27 | return true;
28 | }
29 | }
30 | }
31 | return childFile.isHidden() || childFile.getName().startsWith(".");
32 | }
33 |
34 | public static boolean ignored(String name) {
35 | if( name == null ) {
36 | return false; //indicates the root of Path
37 | }
38 | if( name.equals(".mil") ) { // usually ignore resources starting with a dot, but special case for .mil directory
39 | return false;
40 | }
41 | return name.startsWith(".");
42 | }
43 |
44 | public static boolean ignored(Path p) {
45 | while (p != null && p.getName() != null ) {
46 | if (Utils.ignored(p.getName())) {
47 | return true;
48 | }
49 | p = p.getParent();
50 | }
51 | return false;
52 | }
53 |
54 | public static Map toMap(File[] files) {
55 | Map map = new HashMap<>();
56 | if (files != null) {
57 | for (File r : files) {
58 | map.put(r.getName(), r);
59 | }
60 | }
61 | return map;
62 | }
63 |
64 | public static Map toMap(List triplets) {
65 | Map map = new HashMap<>();
66 | if (triplets != null) {
67 | for (ITriplet r : triplets) {
68 | map.put(r.getName(), r);
69 | }
70 | }
71 | return map;
72 | }
73 |
74 | public static File toFile(File root, Path path) {
75 | File f = root;
76 | for (String fname : path.getParts()) {
77 | f = new File(f, fname);
78 | }
79 | return f;
80 | }
81 |
82 | public static String toType(File child) {
83 | return child.isDirectory() ? "d" : "f";
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/WriteThroughBlobStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import org.hashsplit4j.api.BlobStore;
4 |
5 | /**
6 | * Always write to both
7 | *
8 | * getBlob reads from primary only
9 | *
10 | * hasBlob reads from secondary only
11 | *
12 | * @author brad
13 | */
14 | public class WriteThroughBlobStore implements BlobStore {
15 | private final BlobStore primary;
16 | private final BlobStore secondary;
17 |
18 | public WriteThroughBlobStore(BlobStore primary, BlobStore secondary) {
19 | this.primary = primary;
20 | this.secondary = secondary;
21 | }
22 |
23 | @Override
24 | public void setBlob(String hash, byte[] bytes) {
25 | primary.setBlob(hash, bytes);
26 | secondary.setBlob(hash, bytes);
27 | }
28 |
29 | @Override
30 | public byte[] getBlob(String hash) {
31 | byte[] arr = primary.getBlob(hash);
32 | if( arr == null ) {
33 | arr = secondary.getBlob(hash);
34 | }
35 | return arr;
36 | }
37 |
38 | @Override
39 | public boolean hasBlob(String hash) {
40 | return secondary.hasBlob(hash);
41 | }
42 |
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/WriteThroughHashStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync;
2 |
3 | import java.util.List;
4 | import org.hashsplit4j.api.Fanout;
5 | import org.hashsplit4j.api.HashStore;
6 |
7 | /**
8 | *
9 | * @author brad
10 | */
11 | public class WriteThroughHashStore implements HashStore{
12 | private final HashStore primary;
13 | private final HashStore secondary;
14 |
15 | public WriteThroughHashStore(HashStore primary, HashStore secondary) {
16 | this.primary = primary;
17 | this.secondary = secondary;
18 | }
19 |
20 | @Override
21 | public void setChunkFanout(String hash, List blobHashes, long actualContentLength) {
22 | primary.setChunkFanout(hash, blobHashes, actualContentLength);
23 | secondary.setChunkFanout(hash, blobHashes, actualContentLength);
24 | }
25 |
26 | @Override
27 | public void setFileFanout(String hash, List fanoutHashes, long actualContentLength) {
28 | primary.setFileFanout(hash, fanoutHashes, actualContentLength);
29 | secondary.setFileFanout(hash, fanoutHashes, actualContentLength);
30 | }
31 |
32 | @Override
33 | public Fanout getFileFanout(String fileHash) {
34 | Fanout f = primary.getFileFanout(fileHash);
35 | return f;
36 | }
37 |
38 | @Override
39 | public Fanout getChunkFanout(String fanoutHash) {
40 | return primary.getChunkFanout(fanoutHash);
41 | }
42 |
43 | @Override
44 | public boolean hasChunk(String fanoutHash) {
45 | return secondary.hasChunk(fanoutHash);
46 | }
47 |
48 | @Override
49 | public boolean hasFile(String fileHash) {
50 | return secondary.hasFile(fileHash);
51 | }
52 |
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/event/DownloadSyncEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 McEvoy Software Ltd
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package io.milton.sync.event;
18 |
19 | import io.milton.event.Event;
20 | import java.io.File;
21 |
22 |
23 | /**
24 | *
25 | * @author brad
26 | */
27 | public class DownloadSyncEvent implements Event{
28 | private final File localFile;
29 |
30 | public DownloadSyncEvent(File localFile) {
31 | this.localFile = localFile;
32 | }
33 |
34 | public File getLocalFile() {
35 | return localFile;
36 | }
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/event/EventUtils.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.event;
2 |
3 | import io.milton.event.Event;
4 | import io.milton.event.EventManager;
5 | import io.milton.http.exceptions.BadRequestException;
6 | import io.milton.http.exceptions.ConflictException;
7 | import io.milton.http.exceptions.NotAuthorizedException;
8 |
9 | /**
10 | *
11 | * @author brad
12 | */
13 | public class EventUtils {
14 |
15 | public static void fireQuietly(EventManager eventManager, Event e) {
16 | try {
17 | eventManager.fireEvent( e );
18 | } catch( ConflictException | BadRequestException | NotAuthorizedException ex ) {
19 | throw new RuntimeException( ex );
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/event/FileChangedEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 McEvoy Software Ltd
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package io.milton.sync.event;
18 |
19 | import io.milton.event.Event;
20 | import java.io.File;
21 |
22 |
23 | /**
24 | * Fired when one or more changed files are detected in the file system.
25 | *
26 | * This will usually inform the sync program after local triplet store has been updated.
27 | * The sync client will then scan the local triplet store against the remote.
28 | *
29 | * @author brad
30 | */
31 | public class FileChangedEvent implements Event{
32 | private final File root;
33 | private final String rootHash;
34 |
35 |
36 | public FileChangedEvent(File root, String rootHash) {
37 | this.root = root;
38 | this.rootHash = rootHash;
39 | }
40 |
41 | public File getRoot() {
42 | return root;
43 | }
44 |
45 | public String getRootHash() {
46 | return rootHash;
47 | }
48 |
49 |
50 |
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/event/FinishedSyncEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 McEvoy Software Ltd
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package io.milton.sync.event;
18 |
19 | import io.milton.event.Event;
20 |
21 |
22 | /**
23 | *
24 | * @author brad
25 | */
26 | public class FinishedSyncEvent implements Event{
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/event/ScanEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 McEvoy Software Ltd
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package io.milton.sync.event;
18 |
19 | import io.milton.event.Event;
20 |
21 |
22 | /**
23 | *
24 | * @author brad
25 | */
26 | public class ScanEvent implements Event{
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/event/TransferProgressEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 McEvoy Software Ltd.
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | * You should have received a copy of the GNU General Public License
13 | * along with this program. If not, see .
14 | */
15 | package io.milton.sync.event;
16 |
17 | import io.milton.event.Event;
18 |
19 | /**
20 | *
21 | * @author brad
22 | */
23 | public class TransferProgressEvent implements Event {
24 |
25 | private final long bytesRead;
26 | private final Long totalBytes;
27 | private final String fileName;
28 |
29 | public TransferProgressEvent(long bytesRead, Long totalBytes, String fileName) {
30 | this.bytesRead = bytesRead;
31 | this.totalBytes = totalBytes;
32 | this.fileName = fileName;
33 | }
34 |
35 | public long getBytesRead() {
36 | return bytesRead;
37 | }
38 |
39 | public String getFileName() {
40 | return fileName;
41 | }
42 |
43 | public long getTotalBytes() {
44 | return totalBytes;
45 | }
46 |
47 | public int getPercent() {
48 | if (totalBytes > 0) {
49 | return (int)(bytesRead * 100 / totalBytes);
50 | } else {
51 | return 0;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/event/UploadSyncEvent.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.event;
2 |
3 | import io.milton.event.Event;
4 | import java.io.File;
5 |
6 |
7 | /**
8 | *
9 | * @author brad
10 | */
11 |
12 |
13 | public class UploadSyncEvent implements Event{
14 | private final File localFile;
15 |
16 | public UploadSyncEvent(File localFile) {
17 | this.localFile = localFile;
18 | }
19 |
20 | public File getLocalFile() {
21 | return localFile;
22 | }
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/triplets/BlobUtils.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.triplets;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.IOException;
6 | import java.io.RandomAccessFile;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import org.apache.commons.io.IOUtils;
10 | import io.milton.sync.Utils;
11 | import org.hashsplit4j.store.FileBlobStore;
12 | import org.hashsplit4j.triplets.ITriplet;
13 | import org.hashsplit4j.triplets.Triplet;
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 |
17 | /**
18 | * Just moving random stuff out of JdbcLocalTripletStore to make it tidier
19 | *
20 | * @author brad
21 | */
22 | public class BlobUtils {
23 |
24 | private static final Logger log = LoggerFactory.getLogger(BlobUtils.class);
25 |
26 | public static List toTriplets(File parent, List records) {
27 | List list = new ArrayList<>();
28 | for (CrcDao.CrcRecord r : records) {
29 | File child = new File(parent, r.name);
30 | if (!child.exists()) {
31 | // cached information is out of date
32 | // TODO: should regenerate triplets, but should rarely happen
33 | log.warn("Stale triplet information. Child does not exist: " + child.getAbsolutePath());
34 | } else {
35 | Triplet t = new Triplet();
36 | t.setHash(r.crc);
37 | t.setName(r.name);
38 | t.setType(Utils.toType(child));
39 | list.add(t);
40 | }
41 | }
42 | return list;
43 | }
44 |
45 | public static byte[] loadAndVerify(File currentScanFile, BlobDao.BlobVector v) throws FileNotFoundException, IOException {
46 | RandomAccessFile raf = null;
47 | try {
48 | raf = new RandomAccessFile(currentScanFile, "r");
49 | return FileBlobStore.readBytes(raf, v.offset, v.length, v.crc); // implicitly verifies against given crc, will throw IOException if not valid
50 | } finally {
51 | IOUtils.closeQuietly(raf);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/triplets/BlockingBlobStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.triplets;
2 |
3 | import org.hashsplit4j.api.BlobStore;
4 |
5 | /**
6 | *
7 | * @author brad
8 | */
9 | public interface BlockingBlobStore extends BlobStore{
10 | /**
11 | * Implementations may block here to wait for async operations to complete
12 | *
13 | */
14 | void checkComplete() throws Exception;
15 | }
16 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/triplets/BlockingHashStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.triplets;
2 |
3 | import org.hashsplit4j.api.HashStore;
4 |
5 | /**
6 | *
7 | * @author brad
8 | */
9 | public interface BlockingHashStore extends HashStore{
10 | /**
11 | * Implementations may block here to wait for async operations to complete
12 | *
13 | */
14 | void checkComplete() throws Exception;
15 | }
16 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/triplets/HttpTripletStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.triplets;
2 |
3 | import io.milton.common.Path;
4 | import java.io.ByteArrayInputStream;
5 | import java.io.IOException;
6 | import java.util.HashMap;
7 | import java.util.List;
8 | import java.util.Map;
9 | import io.milton.httpclient.Host;
10 | import org.hashsplit4j.triplets.HashCalc;
11 | import org.hashsplit4j.triplets.ITriplet;
12 |
13 | /**
14 | * Loads triplets from a remote server over HTTP. Can lookup triplets by path
15 | * or by parent directory hash
16 | *
17 | * @author brad
18 | */
19 | public class HttpTripletStore implements ParentHashAwareTripletStore {
20 | private final Host host;
21 | private final Path rootPath;
22 | private final HashCalc hashCalc = HashCalc.getInstance();
23 |
24 | /**
25 | *
26 | * @param httpClient
27 | * @param rootPath
28 | */
29 | public HttpTripletStore(Host httpClient, Path rootPath) {
30 | this.host = httpClient;
31 | this.rootPath = rootPath;
32 | }
33 |
34 | @Override
35 | public List getTriplets(Path path) {
36 | Path p = rootPath.add(path);
37 | p = p.child("_triplets");
38 | try {
39 | byte[] arrRemoteTriplets = host.doGet(p);
40 | List triplets = hashCalc.parseTriplets(new ByteArrayInputStream(arrRemoteTriplets));
41 | return triplets;
42 | } catch (IOException ex) {
43 | throw new RuntimeException(p.toString(), ex);
44 | } catch(Throwable e) {
45 | throw new RuntimeException(p.toString(), e);
46 | }
47 | }
48 |
49 | @Override
50 | public List getTriplets(String hash) {
51 | Path p = Path.root.child("_hashes").child("dirhashes").child(hash+"");
52 | Map params = new HashMap<>();
53 |
54 | try {
55 | byte[] arrRemoteTriplets = host.doGet(p, params);
56 | List triplets = hashCalc.parseTriplets(new ByteArrayInputStream(arrRemoteTriplets));
57 | return triplets;
58 | } catch (IOException ex) {
59 | throw new RuntimeException(p.toString(), ex);
60 | } catch(Throwable e) {
61 | throw new RuntimeException(p.toString(), e);
62 | }
63 | }
64 |
65 | @Override
66 | public String refreshDir(Path path) {
67 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/triplets/MemorySyncHashCache.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.triplets;
2 |
3 | import java.io.File;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | /**
8 | *
9 | * @author brad
10 | */
11 |
12 |
13 | public class MemorySyncHashCache implements SyncHashCache {
14 |
15 | private final Map mapOfHashes = new HashMap<>();
16 |
17 | @Override
18 | public String get(File file) {
19 | String key = getKey(file);
20 | return mapOfHashes.get(key);
21 | }
22 |
23 | @Override
24 | public void put(File file, String hash) {
25 | String key = getKey(file);
26 | mapOfHashes.put(key, hash);
27 | }
28 |
29 | private String getKey(File file) {
30 | String key = file.getAbsolutePath() + "-" + file.length() + "-" + file.lastModified();
31 | return key;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/triplets/ParentHashAwareTripletStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.triplets;
2 |
3 |
4 | import java.util.List;
5 | import org.hashsplit4j.triplets.ITriplet;
6 |
7 | /**
8 | *
9 | * @author brad
10 | */
11 |
12 |
13 | public interface ParentHashAwareTripletStore extends TripletStore {
14 | /**
15 | * Get the list of triplets when the directory hash is known
16 | *
17 | * @param hash
18 | * @return
19 | */
20 | List getTriplets(String hash);
21 | }
22 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/triplets/PausableTripletStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.triplets;
2 |
3 | /**
4 | *
5 | * @author brad
6 | */
7 |
8 |
9 | public interface PausableTripletStore extends TripletStore {
10 | void setPaused(boolean b);
11 | }
12 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/triplets/SyncHashCache.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.triplets;
2 |
3 | import java.io.File;
4 |
5 | /**
6 | *
7 | * @author brad
8 | */
9 |
10 |
11 | public interface SyncHashCache {
12 | public String get(File file);
13 | public void put(File file, String hash);
14 | }
15 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/java/io/milton/sync/triplets/TripletStore.java:
--------------------------------------------------------------------------------
1 | package io.milton.sync.triplets;
2 |
3 | import io.milton.common.Path;
4 | import java.util.List;
5 | import org.hashsplit4j.triplets.ITriplet;
6 |
7 | /**
8 | * A Triplet describes a member within a directory/collection, but its
9 | * name, hash, and type (and metaId, but lets ignore that because it
10 | * makes it a Quadlet which sounds crap)
11 | *
12 | * A list of Triplets defines the state of a directory/collection
13 | *
14 | * This interface defines a means of getting a list of triplets for a local
15 | * or remote directory
16 | *
17 | * @author brad
18 | */
19 | public interface TripletStore {
20 | /**
21 | * Return the list of triplets for the given path (which might be
22 | * relative to a root location)
23 | *
24 | * @param path
25 | * @return - the list of triplets defining the state of the directory, or null
26 | * if the directory was not found
27 | */
28 | List getTriplets(Path path);
29 |
30 | /**
31 | * Re-calc the directory hash and persist it
32 | *
33 | * @param path
34 | * @return
35 | */
36 | String refreshDir(Path path);
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/resources/Images/logo-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync/src/main/resources/Images/logo-dark.png
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/resources/Images/upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync/src/main/resources/Images/upload.png
--------------------------------------------------------------------------------
/milton-cloud-sync/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Set root logger level to DEBUG and its only appender to A1.
2 | log4j.rootLogger=INFO, A1
3 |
4 | # A1 is set to be a ConsoleAppender.
5 | log4j.appender.A1=org.apache.log4j.ConsoleAppender
6 | log4j.appender.A1.layout=org.apache.log4j.PatternLayout
7 | log4j.appender.A1.layout.ConversionPattern=%-5p %c %x - %m%n
8 |
9 | log4j.logger.io.milton=INFO
10 | log4j.logger.io.milton.event=INFO
11 | log4j.logger.io.milton.http.HttpManager=INFO
12 | log4j.logger.io.milton.http.webdav2=INFO
13 | log4j.logger.io.milton.http.fs=INFO
14 | log4j.logger.io.milton.http.json=INFO
15 | log4j.logger.io.milton.http.http11.auth=INFO
16 | log4j.logger.io.milton.http.http11.auth.CookieAuthenticationHandler=INFO
17 | log4j.logger.io.milton.cloud.server.web.SpliffySecurityManager=INFO
18 | log4j.logger.io.milton.cloud.server.web.SpliffyResourceFactory=INFO
19 | log4j.logger.com.fuselms.apps.learning.LearningApp=INFO
20 | log4j.logger.io.milton.cloud.server.apps.content.ContentApp=INFO
21 | log4j.logger.io.milton.cloud.server.apps.orgs.OrgIdsCsv=INFO
22 |
23 | log4j.logger.org.hibernate.cache.ehcache=INFO
24 | log4j.logger.org.hashsplit4j.api.Parser=INFO
25 | log4j.logger.org.springframework=WARN
26 | log4j.logger.org.hibernate=INFO
27 | log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=INFO
28 | log4j.logger.org.hibernate.SQL=INFO
29 | log4j.logger.org.apache=INFO
30 | log4j.logger.net.fortuna.ical4j=INFO
31 | log4j.logger.org.mortbay.log=INFO
32 | log4j.logger.eu.medsea=INFO
33 | log4j.logger.net.sf.ehcache=INFO
34 | log4j.logger.net.sf.json=WARN
35 |
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch1/a/a-changed.txt:
--------------------------------------------------------------------------------
1 | hello
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch1/a/a-deleted.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch1/a/a-not-changed.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch1/c/c-not-changed.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch2/a/a-changed.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch2/a/a-new1.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch2/a/a-not-changed.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch2/c/c-not-changed.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch3/a/a-changed.txt:
--------------------------------------------------------------------------------
1 | hello
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch3/a/a-deleted.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/milton-cloud-sync/src/test/resources/branch3/a/a-not-changed.txt:
--------------------------------------------------------------------------------
1 | hello world
--------------------------------------------------------------------------------
/milton-cloud-sync/~/syncdb.h2.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-sync/~/syncdb.h2.db
--------------------------------------------------------------------------------
/milton-cloud-sync/~/syncdb.trace.db:
--------------------------------------------------------------------------------
1 | 08-22 01:08:52 jdbc[2]: Connection not closed
2 | java.lang.Exception: Stack Trace
3 | at org.h2.jdbc.JdbcConnection.(JdbcConnection.java:121)
4 | at org.h2.jdbc.JdbcConnection.(JdbcConnection.java:94)
5 | at org.h2.Driver.connect(Driver.java:72)
6 | at java.sql.DriverManager.getConnection(DriverManager.java:664)
7 | at java.sql.DriverManager.getConnection(DriverManager.java:247)
8 | at org.apache.commons.dbcp.DriverManagerConnectionFactory.createConnection(DriverManagerConnectionFactory.java:75)
9 | at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582)
10 | at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1148)
11 | at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
12 | at com.ettrema.db.UseConnection.use(UseConnection.java:28)
13 | at io.milton.sync.JdbcHashCache.(JdbcHashCache.java:54)
14 | at io.milton.sync.SyncCommand.start(SyncCommand.java:76)
15 | at GUISync.MainPage.updateJobList(MainPage.java:488)
16 | at GUISync.MainPage.(MainPage.java:65)
17 | at GUISync.base.(base.java:22)
18 | at GUISync.base.protect(base.java:87)
19 | at GUISync.base.main(base.java:59)
20 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/mem.h2.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kademi/milton-cloud/579f6b0e0ec211252da431ecc2c43667edb4d3a6/milton-cloud-vfs/mem.h2.db
--------------------------------------------------------------------------------
/milton-cloud-vfs/nb-configuration.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
16 | all
17 |
18 |
19 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/nbactions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CUSTOM-install skip tests
5 | install skip tests
6 |
7 | install
8 |
9 |
10 | true
11 |
12 |
13 |
14 | CUSTOM-deploy
15 | deploy
16 |
17 | deploy
18 |
19 |
20 |
21 | debug
22 |
23 | jar
24 |
25 |
26 | jetty:run
27 |
28 |
29 | true
30 | maven
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/common/CurrentDateService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 McEvoy Software Ltd
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program. If not, see .
16 | */
17 | package io.milton.cloud.common;
18 |
19 | import static io.milton.context.RequestContext.C;
20 | import io.milton.http.DateUtils;
21 | import java.util.Date;
22 |
23 | /**
24 | * Simple interface to allow externalising the current date, ie for testing
25 | *
26 | * @author brad
27 | */
28 | public interface CurrentDateService {
29 |
30 | public static Date now() {
31 | Date now = C(CurrentDateService.class).getNow();
32 | return now;
33 | }
34 |
35 | Date getNow();
36 |
37 | /**
38 | * Should apply localisation per user
39 | *
40 | * @param s
41 | * @return
42 | * @throws io.milton.http.DateUtils.DateParseException
43 | */
44 | Date parseDate(String s) throws DateUtils.DateParseException;
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/common/MutableCurrentDateService.java:
--------------------------------------------------------------------------------
1 | package io.milton.cloud.common;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * Allows modification of the "current" date for testing purposes
7 | *
8 | * @author brad
9 | */
10 | public class MutableCurrentDateService extends DefaultCurrentDateService implements CurrentDateService {
11 |
12 | private Date artificalDate = null;
13 | private Long dateOffset = null;
14 |
15 | @Override
16 | public Date getNow() {
17 | if (artificalDate != null) {
18 | return artificalDate;
19 | } else if (dateOffset != null) {
20 | long tm = System.currentTimeMillis() + dateOffset;
21 | return new Date(tm);
22 | } else {
23 | return new Date();
24 | }
25 |
26 | }
27 |
28 | public Date getArtificalDate() {
29 | return artificalDate;
30 | }
31 |
32 | public void setArtificalDate(Date artificalDate) {
33 | this.artificalDate = artificalDate;
34 | }
35 |
36 | /**
37 | * Number of milliseconds to offset the actual datetime by
38 | *
39 | * @return
40 | */
41 | public Long getDateOffset() {
42 | return dateOffset;
43 | }
44 |
45 | public void setDateOffset(Long dateOffset) {
46 | this.dateOffset = dateOffset;
47 | }
48 |
49 | public void addHours(long d) {
50 | setDateOffset(1000 * 60 * 60 * d);
51 | }
52 |
53 | /**
54 | * Set the current date offset to 1 day
55 | */
56 | public void addDay() {
57 | setDateOffset(1000 * 60 * 60 * 24l);
58 | }
59 |
60 | public void addDays(long d) {
61 | setDateOffset(1000 * 60 * 60 * 24 * d);
62 | }
63 |
64 | /**
65 | * Set the current date offset to 1 week
66 | */
67 | public void addWeek() {
68 | setDateOffset(1000 * 60 * 60 * 24 * 7l);
69 | }
70 |
71 | public void addWeeks(long i) {
72 | setDateOffset(1000 * 60 * 60 * 24 * 7 * i);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/common/With.java:
--------------------------------------------------------------------------------
1 | package io.milton.cloud.common;
2 |
3 | /**
4 | * General purpose callback interface
5 | *
6 | * @author brad
7 | */
8 | public interface With {
9 | O use(T t) throws Exception;
10 | }
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/process/AbstractRule.java:
--------------------------------------------------------------------------------
1 |
2 | package io.milton.cloud.process;
3 |
4 | import java.io.Serializable;
5 |
6 | public abstract class AbstractRule implements Rule, Serializable {
7 |
8 | private static final long serialVersionUID = 1L;
9 |
10 | public boolean toBool(Object o) {
11 | if (o == null) {
12 | return false;
13 | } else if (o instanceof Boolean) {
14 | return (Boolean) o;
15 | } else if (o instanceof Integer) {
16 | Integer i = (Integer) o;
17 | return i.intValue() == 0;
18 | } else if (o instanceof String) {
19 | String s = (String) o;
20 | s = s.toLowerCase();
21 | return s.equals("true") || s.equals("yes");
22 | } else {
23 | throw new RuntimeException("Unsupported boolean type: " + o.getClass());
24 | }
25 |
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/process/ActionHandler.java:
--------------------------------------------------------------------------------
1 | package io.milton.cloud.process;
2 |
3 | /**
4 | * Instances of this are fired on various events, such as entering or leaving states
5 | *
6 | * Must have a contructor (Element el)
7 | *
8 | * @author brad
9 | */
10 | public interface ActionHandler {
11 |
12 | /**
13 | * Perform the action
14 | *
15 | * @param context
16 | */
17 | void process(ProcessContext context);
18 | }
19 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/process/AndRule.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 McEvoy Software Ltd.
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Affero General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | * You should have received a copy of the GNU General Public License
13 | * along with this program. If not, see .
14 | */
15 | package io.milton.cloud.process;
16 |
17 | import java.util.List;
18 |
19 | /**
20 | *
21 | * @author brad
22 | */
23 | public class AndRule implements Rule {
24 |
25 | private List rules;
26 |
27 | public AndRule(List rules) {
28 | this.rules = rules;
29 | }
30 |
31 |
32 |
33 | @Override
34 | public Boolean eval(ProcessContext context) {
35 | for( Rule r : rules ) {
36 | boolean result = r.eval(context);
37 | if( !result ) {
38 | return false;
39 | }
40 | }
41 | return true;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/process/BeanPropertyExpression.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 McEvoy Software Ltd.
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Affero General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | * You should have received a copy of the GNU General Public License
13 | * along with this program. If not, see .
14 | */
15 | package io.milton.cloud.process;
16 |
17 | import java.lang.reflect.InvocationTargetException;
18 | import org.apache.commons.beanutils.PropertyUtils;
19 |
20 | /**
21 | *
22 | * @author brad
23 | */
24 | public class BeanPropertyExpression implements Expression {
25 |
26 | private String beanPath;
27 |
28 | public BeanPropertyExpression(String beanPath) {
29 | this.beanPath = beanPath;
30 | }
31 |
32 | @Override
33 | public Object eval(ProcessContext context) {
34 | Object val = null;
35 | try {
36 | val = PropertyUtils.getProperty(context, beanPath);
37 | } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) {
38 | throw new RuntimeException(beanPath, ex);
39 | }
40 | return val;
41 | }
42 |
43 | public String getBeanPath() {
44 | return beanPath;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/process/ConstantExpression.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013 McEvoy Software Ltd.
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU Affero General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | * You should have received a copy of the GNU General Public License
13 | * along with this program. If not, see .
14 | */
15 | package io.milton.cloud.process;
16 |
17 | /**
18 | *
19 | * @author brad
20 | */
21 | public class ConstantExpression implements Expression {
22 |
23 | private Object value;
24 |
25 | public ConstantExpression(Object value) {
26 | this.value = value;
27 | }
28 |
29 |
30 | @Override
31 | public Object eval(ProcessContext context) {
32 | return value;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/process/ContainsRule.java:
--------------------------------------------------------------------------------
1 | /*
2 | */
3 | package io.milton.cloud.process;
4 |
5 | import io.milton.context.Registration;
6 | import java.lang.reflect.InvocationTargetException;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import org.apache.commons.beanutils.BeanUtils;
10 |
11 | /**
12 | * Returns true if the given List contains at least 1 item which has a property
13 | * that matches the given value
14 | *
15 | * @author brad
16 | */
17 | public class ContainsRule implements Rule {
18 |
19 | private String propertyName;
20 | private String value;
21 |
22 | public ContainsRule(String propertyName, String value) {
23 | this.propertyName = propertyName;
24 | this.value = value;
25 | }
26 |
27 |
28 | @Override
29 | public Boolean eval(ProcessContext context) {
30 | try {
31 | List arg = context.get(List.class);
32 | if (arg == null) {
33 | return false;
34 | }
35 | for (Object o : arg) {
36 | String propVal = BeanUtils.getProperty(o, propertyName);
37 | if( propVal != null && propVal.equals(value)) {
38 | return true;
39 | }
40 | }
41 | return false;
42 | } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
43 | throw new RuntimeException(e);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/process/Expression.java:
--------------------------------------------------------------------------------
1 | package io.milton.cloud.process;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | *
7 | * @author brad
8 | */
9 | public interface Expression extends Serializable {
10 |
11 |
12 | /**
13 | * Evaluate this rule on the given context
14 | *
15 | * @param context
16 | * @return - true to indicate this rule is satisfied
17 | */
18 | T eval(ProcessContext context);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/milton-cloud-vfs/src/main/java/io/milton/cloud/process/ListFilterExpression.java:
--------------------------------------------------------------------------------
1 | /*
2 | */
3 | package io.milton.cloud.process;
4 |
5 | import io.milton.context.Registration;
6 | import java.lang.reflect.InvocationTargetException;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import org.apache.commons.beanutils.BeanUtils;
10 |
11 | /**
12 | * Filter out elements of a list which do not match the bean property expression
13 | *
14 | * Can take a child expression, in which case it is passed the filtered list
15 | * and returns the child's result
16 | *
17 | * @author brad
18 | */
19 | public class ListFilterExpression implements Expression