9 Star 14 Fork 4

onecoder / shurnim-storage

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

shurnim-storage

Shurnim icon

目录

背景介绍

Shurnim (鼠尼玛),是我和我老婆曾经养过的一只仓鼠的名字。
shurnim-storage,是一个插件式云存储/网盘同步管理工具。是在参加又拍云开发大赛的过程中设计并开发。

项目介绍

shurnim-storage 的设计初衷是给大家提供一个可方便扩展的云存储/网盘同步工具。分后端接口和前端UI界面两部分。

由于目前各种云存储和网盘系统层出不穷,单一工具往往支持支持某几个特定存储之间的同步,如又拍云七牛云存储的同步工具,此时如若想同步到其他存则可能需要新的工具,给用户带来不便。shurnim-storage 正是为了解决此问题而设计的。

shurnim-storage中,用户使用的固定的统一的后端接口。而所有云存储/网盘API的支持则是以插件的形式部署到系统中的。如此,如果用户想要一个从又拍云Dropbox的同步工具,则只需要在原有基础上,增加Dropbox的插件,即可实现互通,方便快捷。

同时,后端统一接口的设计也考虑到界面开发的需求,可直接通过后端提供的接口开发具有上述扩展功能的云存储UI工具。

目前,后端整体框架的核心部分已经基本开发完成。只需逐步补充后端接口和插件开发接口的定义即可。但由于个人时间和能力所限,UI部分没有开发,有兴趣的同学可以一试。

使用说明

获取代码

另外你也可以通过OSChina的Maven库获取依赖,或者自己编译jar包。

  • maven

    1. 加入OSC仓库

       	<repositories>
       		<repository>
       			<id>nexus</id>
       			<name>local private nexus</name>
       			<url>http://maven.oschina.net/content/groups/public/</url>
       			<releases>
       				<enabled>true</enabled>
       			</releases>
       			<snapshots>
       				<enabled>false</enabled>
       			</snapshots>
       		</repository>
       	</repositories>
    2. 加入依赖

       <dependency>
         <groupId>com.coderli</groupId>
         <artifactId>shurnim-storage</artifactId>
         <version>0.1-alpha</version>
       </dependency>
  • Gradle 编译Jar

在项目目录执行

gradle jar

开发插件

shurnim-storage中,插件就像一块一块的积木,不但支撑着框架的功能,也是框架可扩展性的基石。开发一个插件,仅需两步:

  1. 实现PluginAPI接口
package com.coderli.shurnim.storage.plugin;

import java.io.File;
import java.util.List;

import com.coderli.shurnim.storage.plugin.model.Resource;

/**
 * 各种云存储插件需要实现的通用接口
 * 
 * @author OneCoder
 * @date 2014年4月22日 下午9:43:41
 * @website http://www.coderli.com
 */
public interface PluginAPI {

	/**
	 * 初始化接口
	 * 
	 * @author OneCoder
	 * @date 2014年5月19日 下午10:47:40
	 */
	void init();

	/**
	 * 获取子资源列表
	 * 
	 * @param parentPath
	 * @return
	 * @author OneCoder
	 * @date 2014年4月24日 下午11:29:14
	 */
	List<Resource> getChildResources(String parentPath);

	/**
	 * 下载特定的资源
	 * 
	 * @param parentPath
	 *            目录路径
	 * @param name
	 *            资源名称
	 * @param storePath
	 *            下载资源保存路径
	 * @return
	 * @author OneCoder
	 * @date 2014年4月24日 下午11:30:19
	 */
	Resource downloadResource(String parentPath, String name, String storePath);

	/**
	 * 创建文件夹
	 * 
	 * @param path
	 *            文件夹路径
	 * @param auto
	 *            是否自动创建父目录
	 * @return
	 * @author OneCoder
	 * @date 2014年5月15日 下午10:10:04
	 */
	boolean mkdir(String path, boolean auto);

	/**
	 * 上传资源
	 * 
	 * @param parentPath
	 *            父目录路径
	 * @param name
	 *            资源名称
	 * @param uploadFile
	 *            待上传的本地文件
	 * @return
	 * @author OneCoder
	 * @date 2014年5月15日 下午10:40:13
	 */
	boolean uploadResource(String parentPath, String name, File uploadFile);
}

目前插件的接口列表仅为同步资源设计,如果想要支持更多操作(如删除,查找等),可扩展该接口定义。

接口中,所有的参数和返回值均为shurnim-storage框架中定义的通用模型。因此,您在开发插件过程中需要将特定SDK中的模型转换成接口中提供的模型。

插件实现类只要与shurnim-storage工程在同一个classpath即可使用。您既可以直接在源码工程中开发插件,就如工程里提供的upyunqiniu插件一样,也可以作为独立工程开发,打成jar,放置在同一个classpath下。

upyun插件样例(功能不完整):

package com.coderli.shurnim.storage.upyun.plugin;

import java.io.File;
import java.util.List;

import com.coderli.shurnim.storage.plugin.AbstractPluginAPI;
import com.coderli.shurnim.storage.plugin.model.Resource;
import com.coderli.shurnim.storage.plugin.model.Resource.Type;
import com.coderli.shurnim.storage.upyun.api.UpYun;

public class UpYunPlugin extends AbstractPluginAPI {

	private UpYun upyun;
	private String username;
	private String password;
	private String bucketName;

	public UpYun getUpyun() {
		return upyun;
	}

	public void setUpyun(UpYun upyun) {
		this.upyun = upyun;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getBucketName() {
		return bucketName;
	}

	public void setBucketName(String bucketName) {
		this.bucketName = bucketName;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.coderli.shurnim.storage.plugin.PluginAPI#getChildResources(java.lang
	 * .String)
	 */
	@Override
	public List<Resource> getChildResources(String parentPath) {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.coderli.shurnim.storage.plugin.PluginAPI#downloadResource(java.lang
	 * .String, java.lang.String, java.lang.String)
	 */
	@Override
	public Resource downloadResource(String parentPath, String name,
			String storePath) {
		File storeFile = new File(storePath);
//		if (!storeFile.exists()) {
//			try {
//				storeFile.createNewFile();
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
//		}
		String filePath = getFullPath(parentPath, name);
		upyun.readDir("/api");
		if (upyun.readFile(filePath, storeFile)) {
			Resource result = new Resource();
			result.setName(name);
			result.setPath(parentPath);
			result.setType(Type.FILE);
			result.setLocalFile(storeFile);
			return result;
		}
		return null;
	}

	String getFullPath(String parentPath, String name) {
		if (!parentPath.endsWith(File.separator)) {
			parentPath = parentPath + File.separator;
		}
		return parentPath + name;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.coderli.shurnim.storage.plugin.PluginAPI#mkdir(java.lang.String,
	 * boolean)
	 */
	@Override
	public boolean mkdir(String path, boolean auto) {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.coderli.shurnim.storage.plugin.PluginAPI#uploadResource(java.lang
	 * .String, java.lang.String, java.io.File)
	 */
	@Override
	public boolean uploadResource(String parentPath, String name,
			File uploadFile) {
		// TODO Auto-generated method stub
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.coderli.shurnim.storage.plugin.AbstractPluginAPI#init()
	 */
	@Override
	public void init() {
		upyun = new UpYun(bucketName, username, password);
	}

}
  1. 编写插件配置文件
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
	<id>qiniu</id>
	<name>七牛云存储</name>
	<api>
		<className>com.coderli.shurnim.storage.qiniu.QiniuPlugin</className>
		<params>
			<param name="access_key" displayName="ACCESS_KEY">EjREKHI_GFXbQzyrKdVhhXrIRyj3fRC1s9UmZPZO
			</param>
			<param name="secret_key" displayName="SECRET_KEY">88NofFWUvkfJ6T6rGRxlDSZOQxWkIxY2IsFIXJLX
			</param>
			<param name="bucketName" displayName="空间名">onecoder
			</param>
		</params>
	</api>
</plugin>
  • id 为该插件在shurnim-storage框架下的唯一标识,不可重复,必填。 * name 为显示值,为UI开发提供可供显示的有语义的值。 * className 为插件接口实现类的完整路径。必填 * params/param 为插件需要用户配置的参数列表。其中
    • name 代表参数名,需要与接口实现类中的参数名严格一致,且必须有相应的set方法的格式要求严格,即set+首字母大写的参数名。例如:setAccess_key(String arg); 目前只支持String类型的参数。
    • displayName 为参数显示名,同样是为了UI开发的考虑,方便用户开发出可根据参数列表动态显示的UI界面。
    • 参数的值可以直接配置在配置文件中,也可以在运行期动态赋值。直接配置值,对于直接使用后端接口来说较为方便。对于UI开发来说,运行期动态赋值更为合理。
在使用源码工程时,插件配置文件统一放置在工程的*plugins*目录下。你也可以统一放置在任何位置。此时,在构造后端接口实例时,需要告知接口该位置。

使用ShurnimStorage接口

接口介绍

ShurnimStorage接口是shurinm-storage框架全局的也是唯一的接口,目前定义如

package com.coderli.shurnim.storage;

import java.util.List;
import java.util.Map;

import com.coderli.shurnim.storage.plugin.model.Plugin;
import com.coderli.shurnim.storage.plugin.model.Resource;

/**
 * 后台模块的全局接口<br>
 * 通过该接口使用后台的全部功能。<br>
 * 使用方式:<br>
 * <li>
 * 1.先通过{@link #getSupportedPlugins()}方法获取所有支持的平台/插件列表。 <li>
 * 2.将列表中返回的ID传入对应的接口参数中,进行对应的平台的相关操作。<br>
 * 需要注意的是,不同平台的插件需要给不同的参数赋值,该值可以直接配置在配置文件中。<br>
 * 也可以在运行期动态赋值。(会覆盖配置文件中的值。)<br>
 * 
 * 参数列表的设计,方便UI开发人员动态的根据参数列表生成可填写的控件。并给参数赋值。增强了可扩展性。
 * 
 * @author OneCoder
 * @date 2014年4月22日 下午9:21:58
 * @website http://www.coderli.com
 */
public interface ShurnimStorage {

	/**
	 * 获取当前支持的插件列表<br>
	 * 没有支持的插件的时候可能返回null
	 * 
	 * @return
	 * @author OneCoder
	 * @date 2014年5月7日 下午8:53:25
	 */
	List<Plugin> getSupportedPlugins();

	/**
	 * 给指定的插件的对应参数赋值<br>
	 * 此处赋值会覆盖配置文件中的默认值
	 * 
	 * @param pluginId
	 *            插件ID
	 * @param paramsKV
	 *            参数键值对
	 * @author OneCoder
	 * @date 2014年5月9日 上午12:41:53
	 */
	void setParamValues(String pluginId, Map<String, String> paramsKV);

	/**
	 * 获取插件对应目录下的资源列表
	 * 
	 * @param pluginId
	 *            插件ID
	 * @param path
	 *            指定路径
	 * @return
	 * @author OneCoder
	 * @date 2014年5月11日 上午8:52:00
	 */
	List<Resource> getResources(String pluginId, String path);

	/**
	 * 同步资源
	 * 
	 * @param fromPluginId
	 *            待同步的插件Id
	 * @param toPluginIds
	 *            目标插件Id
	 * @param resource
	 *            待同步的资源
	 * @return 同步结果
	 * @author OneCoder
	 * @date 2014年5月11日 上午11:41:24
	 */
	boolean sycnResource(String fromPluginId, String toPluginId,
				Resource resource) throws Exception;
}

当前接口实际仅包含了获取资源列表getResources和同步资源sycnResource功能,getSupportedPluginssetParamValues实际为辅助接口,在UI开发时较为有用。

同样,您也可以扩展开发该接口增加更多的您喜欢的特性。例如,同时删除给定存储上的文件。当然,这需要插件接口的配合支持。

这里,sycnResource设计成插件间一对一的形式,是考虑到获取同步是否成功的结果的需求。如果您想开发一次同步到多个存储的功能,建议您重新开发您自己的接口实现类,因为默认实现会多次下次资源(每次同步后删除),造成网络资源的浪费。

接口的默认实现类是: DefaultShurnimStorageImpl

使用样例

package com.coderli.shurnim.test.shurnimstorage;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import com.coderli.shurnim.storage.DefaultShurnimStorageImpl;
import com.coderli.shurnim.storage.ShurnimStorage;
import com.coderli.shurnim.storage.plugin.model.Resource;
import com.coderli.shurnim.storage.plugin.model.Resource.Type;

/**
 * 全局接口测试类<br>
 * 时间有限,目前仅作整体接口测试。细粒度的单元测试,随开发补充。
 * 
 * @author OneCoder
 * @date 2014年5月19日 下午10:50:27
 * @website http://www.coderli.com
 */
public class ShurnimStorageTest {

	private static ShurnimStorage shurnim;

	@BeforeClass
	public static void init() {
		shurnim = new DefaultShurnimStorageImpl(
				"/Users/apple/git/shurnim-storage-for-UPYUN/plugins");
	}

	@Test
	public void testSycnResource() {
		Resource syncResource = new Resource();
		syncResource.setPath("/api");
		syncResource.setName("api.html");
		syncResource.setType(Type.FILE);
		try {
			Assert.assertTrue(shurnim.sycnResource("upyun", "qiniu",
					syncResource));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

其他

时间仓促,功能简陋,望您包涵。OneCoder(Blog:http://www.coderli.com)特别希望看到该项目对您哪怕一点点的帮助。任意的意见和建议,欢迎随意与我沟通,联系方式:

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2014 onecoder Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

插件形式的云存储同步工具。可自己根据规范开发自己想支持的云存储插件。后端接口可独立使用。 展开 收起
Java
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/onecoder/shurnim-storage.git
git@gitee.com:onecoder/shurnim-storage.git
onecoder
shurnim-storage
shurnim-storage
master

搜索帮助