# Qiniu Resource Storage SDK for Android

[![@qiniu on weibo](http://img.shields.io/badge/weibo-%40qiniutek-blue.svg)](http://weibo.com/qiniutek)
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE.md)
[![Build Status](https://github.com/qiniu/android-sdk/workflows/Run%20Test%20Cases/badge.svg)](https://github.com/qiniu/android-sdk/actions)
[![codecov](https://codecov.io/gh/qiniu/android-sdk/branch/master/graph/badge.svg)](https://codecov.io/gh/qiniu/android-sdk)
[![Latest Stable Version](http://img.shields.io/maven-central/v/com.qiniu/qiniu-android-sdk.svg)](https://search.maven.org/search?q=a:qiniu-android-sdk)

## 演示代码
https://github.com/qiniudemo/qiniu-lab-android

## 安装

### 运行环境

| Qiniu SDK 版本 | 最低 Android版本   |       依赖库版本           |
|--------------|-----------------|------------------------|
| 8.7.x        |  Android 4.0+     |        okhttp 4+         |
| 8.6.x        |  Android 4.0+     |        okhttp 4+         |
| 8.5.x        |  Android 4.0+     |        okhttp 4+         |
| 8.4.x        |  Android 4.0+     |        okhttp 4+         |
| 8.3.2        |  Android 4.0+     |        okhttp 4+         |
| 8.3.1        |  Android 4.0+     |        okhttp 4+         |
| 8.3.0        |  Android 5.0+     |        okhttp 4+         |
| 8.2.x        |  Android 5.0+     |        okhttp 4+         |
| 8.1.x        |  Android 5.0+     |        okhttp 4+         |
| 8.0.x        |  Android 5.0+     |        okhttp 4+         |
| 7.7.x        |  Android 5.0+     |        okhttp 4+         |
| 7.6.x        |  Android 5.0+     |        okhttp 4+         |
| 7.5.x        |  Android 5.0+     |        okhttp 4+         |
| 7.4.6        |  Android 4.0+     |        okhttp 3.12.6     |
| 7.3.x        |  Android 2.3+     |        okhttp 3.11.0     |
| 7.2.x        |  Android 2.3+     |        okhttp 3+         |
| 7.1.x        |  Android 2.3+     |        okhttp 2.6+       |
| 7.0.8,7.0.9  |  Android 2.2+     | android-async-http 1.4.9 |
| 7.0.7        |  Android 2.2+     | android-async-http 1.4.8 |

### 注意
* 推荐使用最新版：8.7.0
* 7.6.2 ~ 8.3.2 AndroidNetwork.getMobileDbm()可以获取手机信号强度，需要如下权限(API>=18时生效)
```
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
```
* 从7.5.0开始增加了DNS预取和缓存策略，减少dns解析错误
* 如果可以明确 区域 的话，最好指定固定区域，这样可以少一步网络请求，少一步出错的可能。
* 如果使用 Android 4.x ，对应 okhttp 版本请调整至 3.12.+

### 直接安装
将sdk jar文件 复制到项目中去，[jar包下载地址](http://search.maven.org/#search%7Cga%7C1%7Ccom%2Fqiniu%2Fqiniu-android-sdk) , 下载对应的jar包，以及搜索下载对应的依赖库

[happy-dns下载地址](https://repo1.maven.org/maven2/com/qiniu/happy-dns/)

### 通过maven
* Android Studio中添加dependencies 或者 在项目中添加maven依赖
```
// 1. 直接导入
implementation 'com.qiniu:qiniu-android-sdk:8.7.+'

// 2. 如果要修改okhttp依赖的版本，可采用以下方式（强烈建议使用七牛库依赖的okhttp版本）
implementation ('com.qiniu:qiniu-android-sdk:8.7.+'){
    exclude (group: 'com.squareup.okhttp3', module: 'okhttp')
}
implementation 'com.squareup.okhttp3:okhttp:4.9.1'

```
* 如果是eclipse, 也可以直接添加依赖来处理。

## 使用方法
UploadManager 可以创建一次，一直使用。
7.6.2 ~ 8.3.2 会调用AndroidNetwork.getMobileDbm可以获取网络信号强度
需要Manifest.permission.ACCESS_FINE_LOCATION和Manifest.permission.ACCESS_COARSE_LOCATION权限
```java
import com.qiniu.android.storage.UploadManager;
...
String token = "从服务端SDK获取";
UploadManager uploadManager = new UploadManager();
uploadManager.put("Hello, World!".getBytes(), "hello", token,
new UpCompletionHandler() {
    @Override
    public void complete(String key, ResponseInfo info, JSONObject response) {
        LogUtil.i(info);
    }
}, null);
...
```

### 支持使用 HTTP/3 协议发起请求

导入 [HTTP/3 client 插件](https://github.com/qiniu/qiniu-android-curl-plugin)，http3 client 插件依赖于 Android SDK v8.5.0及以上版本

安装导入
```java
// 移除 qiniu-android-sdk 依赖 : implementation 'com.qiniu:qiniu-android-sdk:x.x.+'
implementation 'com.qiniu:qiniu-android-curl-plugin:1.0.0'
```

使用 CurlClient
```java
import com.qiniu.client.curl.CurlClient;
import com.qiniu.android.storage.Configuration;
import com.qiniu.android.storage.UploadManager;

// @param caPath: SSL 证书本地路径；如果想自定义 CA 可设置此选项，此处为 CA 文件的本地路径。
// 				  如果未定义（caPath 配置 null）则使用 SDK 内部提供的 CA 证书，证书来源：https://curl.se/ca/cacert.pem
CurlClient client = new CurlClient(caPath);
Configuration config = new Configuration.Builder()
                .requestClient(client)
                .build();
UploadManager manager = new UploadManager(config);
```

## 测试

``` bash
$ ./gradlew connectedAndroidTest
```

## 常见问题

1).有关Android Studio以及Eclipse安装运行Android Demo步骤，这里以Android Studio为实例:
1.修改 build.gradle
双击打开您的工程目录下的build.gradle，在dependencies中添加一条依赖compile 'com.qiniu:qiniu-android-sdk:7.2.+'，如下所示：
```
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.qiniu:qiniu-android-sdk:7.6.+'
}
```
当然也可以将jar包下载到本地导入到项目中

2.添加相关权限，在 app/src/main 目录中的 AndroidManifest.xml 中增加如下 uses-permission 声明
```
 <uses-permission android:name="android.permission.INTERNET"/>
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
```

3.布局，在res/layout/activity_main.xml添加相应的上传的按钮以及相关控件，以下以一个简单的布局为例:
```
<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textSize="20sp"
        android:layout_marginTop="10dp"
        android:text="七牛云存储 SDK"
        android:id="@+id/textView"
        android:layout_alignParentTop="true"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="上传"
        android:id="@+id/button"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"/>
```
效果如下:
![这里写图片描述](http://7xl4cb.com1.z0.glb.clouddn.com/QQ20160606-1.png)

4.逻辑代码, 为按钮添加上传事件，这里以上传一个byte数组为例，另外，上传的数据可以是文件路径或者文件，以下给出具体的代码:
```
package com.dxy.cloud.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UploadManager;
import com.qiniu.android.storage.UploadOptions;
import org.json.JSONObject;

public class MainActivity extends Activity implements View.OnClickListener {

    //指定upToken, 强烈建议从服务端提供get请求获取, 这里为了掩饰直接指定key
    public static String uptoken = "xxxxx:xxxxx:xxxxx";
    private Button btnUpload;
    private TextView textView;
    private UploadManager uploadManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);
        btnUpload = (Button) findViewById(R.id.button);
        btnUpload.setOnClickListener(this);
        //new一个uploadManager类
        uploadManager = new UploadManager();

    }

    @Override
    public void onClick(View v) {
        LogUtil.i("starting......");
        byte[] data=new byte[]{ 0, 1, 2, 3};
        //设置上传后文件的key
        String upkey = "uploadtest.txt";
        uploadManager.put(data, upkey, uptoken, new UpCompletionHandler() {
            public void complete(String key, ResponseInfo rinfo, JSONObject response) {
                btnUpload.setVisibility(View.INVISIBLE);
                String s = key + ", " + rinfo + ", " + response;
                LogUtil.i(s);
                textView.setTextSize(10);
                String o = textView.getText() + "\r\n\r\n";
                //显示上传后文件的url
                textView.setText(o + s + "\n" + "http://xm540.com1.z0.glb.clouddn.com/" + key);
            }
        }, new UploadOptions(null, "test-type", true, null, null));

    }
}

```
运行的效果图如下:
![这里写图片描述](http://7xl4cb.com1.z0.glb.clouddn.com/QQ20160606-0.png)

**2).有关断点续传，暂停上传，设置自定义变量的用法，这里以一个简单的Demo给出下实现的方法，这里的Demo主要实现从相册选择一张图片上传来说明。**

可以参考放GitHub(Android Studio)上的源码: https://github.com/clouddxy/AndroidDemo
这里直接给出MainActivity中的代码:
```
package com.dxy.cloud.myapplication;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.storage.Configuration;
import com.qiniu.android.storage.KeyGenerator;
import com.qiniu.android.storage.Recorder;
import com.qiniu.android.storage.UpCancellationSignal;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UpProgressHandler;
import com.qiniu.android.storage.UploadManager;
import com.qiniu.android.storage.UploadOptions;
import com.qiniu.android.storage.persistent.FileRecorder;
import com.qiniu.android.utils.UrlSafeBase64;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

public class MainActivity extends Activity {
    private Button button1;
    private Button button2;
    private Button button3;
    private ImageView imageview;
    private Uri imageUri;
    private TextView textview;
    private ProgressBar progressbar;
    public static final int RESULT_LOAD_IMAGE = 1;
    private volatile boolean isCancelled = false;
    UploadManager uploadManager;
    public MainActivity() {
        //断点上传
        String dirPath = "/storage/emulated/0/Download";
        Recorder recorder = null;
        try{
            File f = File.createTempFile("qiniu_xxxx", ".tmp");
            LogUtil.d(f.getAbsolutePath().toString());
            dirPath = f.getParent();
            //设置记录断点的文件的路径
            recorder = new FileRecorder(dirPath);
        } catch(Exception e) {
            e.printStackTrace();
        }

        final String dirPath1 = dirPath;
        //默认使用 key 的url_safe_base64编码字符串作为断点记录文件的文件名。
        //避免记录文件冲突（特别是key指定为null时），也可自定义文件名(下方为默认实现)：
        KeyGenerator keyGen = new KeyGenerator(){
            public String gen(String key, File file){
                // 不必使用url_safe_base64转换，uploadManager内部会处理
                // 该返回值可替换为基于key、文件内容、上下文的其它信息生成的文件名
                String path = key + "_._" + new StringBuffer(file.getAbsolutePath()).reverse();
                LogUtil.d(path);
                File f = new File(dirPath1, UrlSafeBase64.encodeToString(path));
                BufferedReader reader = null;
                try {
                    reader = new BufferedReader(new FileReader(f));
                    String tempString = null;
                    int line = 1;
                    try {
                        while ((tempString = reader.readLine()) != null) {
//							System.out.println("line " + line + ": " + tempString);
                            LogUtil.d("line " + line + ": " + tempString);
                            line++;
                        }

                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } finally {
                        try{
                            reader.close();
                        } catch(Exception e) {
                            e.printStackTrace();
                        }
                    }
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return path;
            }
        };

        Configuration config = new Configuration.Builder()
                // recorder 分片上传时，已上传片记录器
                // keyGen 分片上传时，生成标识符，用于片记录器区分是那个文件的上传记录
                .recorder(recorder, keyGen)
                .build();
        // 实例化一个上传的实例
        uploadManager = new UploadManager(config);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button1 = (Button) findViewById(R.id.bt1);
        button2 = (Button) findViewById(R.id.bt2);
        button3 = (Button) findViewById(R.id.bt3);
        imageview = (ImageView) findViewById(R.id.iv);
        textview = (TextView) findViewById(R.id.tv);
        progressbar = (ProgressBar) findViewById(R.id.pb);

        // final String token = edittext.getText().toString();

        button1.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

                startActivityForResult(i, RESULT_LOAD_IMAGE);

            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK
                && data != null) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };

            Cursor cursor = getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            final String picturePath = cursor.getString(columnIndex);
            LogUtil.d(picturePath);
            cursor.close();

            imageview.setVisibility(View.VISIBLE);
            imageview.setImageBitmap(BitmapFactory.decodeFile(picturePath));

            //自定义参数returnbody
            //"returnBody":"{\"key\":$(key),\"hash\":$(etag),\"fname\":$(fname),\"phone\":$(x:phone)}
            final String token = "xxxxx";
            button2.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {

					//设定需要添加的自定义变量为Map<String, String>类型 并且放到UploadOptions第一个参数里面
                    HashMap<String, String> map = new HashMap<String, String>();
                    map.put("x:phone", "12345678");

                    LogUtil.d("click upload");
                    isCancelled = false;
                    uploadManager.put(picturePath, null, token,
                            new UpCompletionHandler() {
                                public void complete(String key,
                                                     ResponseInfo info, JSONObject res) {
                                    LogUtil.i(key + ",\r\n " + info
                                            + ",\r\n " + res);

                                    if(info.isOK()==true){
                                        textview.setText(res.toString());
                                    }
                                }
                            }, new UploadOptions(map, null, false,
                                    new UpProgressHandler() {
                                        public void progress(String key, double percent){
                                            LogUtil.i(key + ": " + percent);
                                            progressbar.setVisibility(View.VISIBLE);
                                            int progress = (int)(percent*1000);
//											Log.d("qiniu", progress+"");
                                            progressbar.setProgress(progress);
                                            if(progress==1000){
                                                progressbar.setVisibility(View.GONE);
                                            }
                                        }

                                    }, new UpCancellationSignal(){
                                @Override
                                public boolean isCancelled() {
                                    return isCancelled;
                                }
                            }));
                }
            });

            button3.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    isCancelled = true;
                }
            });
        }
    }
}
```
上传过程进度条:
![这里写图片描述](http://7xrnxn.com2.z0.glb.qiniucdn.com/QQ20160402-1.png)
上传后自定义变量回调：
![这里写图片描述](http://7xrnxn.com2.z0.glb.qiniucdn.com/QQ20160402-3.png)

**3).关于从服务器获取Token上传:**
Android SDK为客户端SDK，没有包含token生成实现，为了安全，token都建议通过网络从服务端获取，具体生成代码可以参考"java/python/php/ruby/go"等服务端sdk, 其实也比较简单，可以使用okhttp发送一个简单的get请求就可以了，这里以使用SyncHttpClient为例来说明:
```
package com.example.androidupload;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.loopj.android.http.SyncHttpClient;
import com.loopj.android.http.TextHttpResponseHandler;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UpProgressHandler;
import com.qiniu.android.storage.UploadManager;
import com.qiniu.android.storage.UploadOptions;
import com.qiniu.android.utils.UrlSafeBase64;
import org.apache.http.Header;
import org.json.JSONObject;
import java.io.File;
import java.util.UUID;

public class MainActivity extends Activity {

    private UploadManager uploadManager;
    private final String tag = "MainActivity";

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //设置本地上传的文件的路径
        String path ="/storage/emulated/0/Download/DSC_0770.JPG";
        String aaa = UrlSafeBase64.encodeToString(path);
        File file =new File(path);
    }

    private void upload(final String localPath,final String key)
    {
        Thread thread = new Thread()
        {
            @Override
            public void run() {
                super.run();
                SyncHttpClient client = new SyncHttpClient();
                //获取服务端的token的url
                String url = "http://xxxx/xxxx/xxx";
                client.get(url, new TextHttpResponseHandler() {
                    @Override
                    public void onFailure(int i, Header[] headers, String s, Throwable throwable) {
                    }
                    @Override
                    public void onSuccess(int i, Header[] headers, String s) {
                        LogUtil.i("请求七牛token："+s);
                        JsonParser jsonParser = new JsonParser();
                        JsonElement jsonElement =jsonParser.parse(s);
                        String token = jsonElement.getAsJsonObject().get("uptoken").toString();
                        LogUtil.i("七牛开始上传"+localPath+"\n"+key+"\n"+token);
                        if(uploadManager==null)
                        {
                            uploadManager = new UploadManager();
                        }
                        UploadOptions uploadOptions = new UploadOptions(null, null, false,
                                new UpProgressHandler() {
                                    @Override
                                    public void progress(String key, double percent) {
                                        LogUtil.i("a 七牛上传progress:"+percent+"\n"+key);
                                    }
                                }, null);

                        //调用uploadManager上传
                        uploadManager.put(localPath, key, token, new UpCompletionHandler() {
                            @Override
                            public void complete(String key, com.qiniu.android.http.ResponseInfo info, JSONObject response) {
                                LogUtil.i("a 七牛上传complete:"+key + ",\r\n " + info + ",\r\n " + response);
                            }
                        },uploadOptions);
                    }
                });
            }
        };
        thread.start();
    }
}
```

**4).关于for循环上传:**
可以参考demo:
```
package com.dxy.cloud.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.qiniu.android.http.ResponseInfo;
import com.qiniu.android.storage.UpCompletionHandler;
import com.qiniu.android.storage.UploadManager;
import com.qiniu.android.storage.UploadOptions;
import org.json.JSONObject;

public class MainActivity extends Activity implements View.OnClickListener {

    //指定upToken, 强烈建议从服务端提供get请求获取, 这里为了掩饰直接指定key
    public static String uptoken = "xxxxxxxxx:xxxxxxx:xxxxxxxxxx";
    private Button btnUpload;
    private TextView textView;
    private UploadManager uploadManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);
        btnUpload = (Button) findViewById(R.id.button);
        btnUpload.setOnClickListener(this);
        //new一个uploadManager类
        uploadManager = new UploadManager();
    }

    @Override
    public void onClick(View v) {
        LogUtil.i("starting......");
        byte[] data=new byte[]{ 0, 1, 2, 3, 3, 4, 5, 6,0, 1, 2, 3, 4, 5, 6,0, 1, 2, 3, 4, 5, 6,0, 1, 2, 3, 4, 5, 6,0, 1, 2, 3, 4, 5, 6,0, 1, 2, 3,};

       for(int i=0;i<data.length;i++){
        	String expectKey =UUID.randomUUID().toString();
            uploadManager.put(data, expectKey, uptoken, new UpCompletionHandler() {
                public void complete(String k, ResponseInfo rinfo, JSONObject response) {
                    String s = k + ", "+ rinfo + ", " + response;
                    LogUtil.i(s);
                    String key = getKey(k, response);
                    String o = hint.getText() + "\r\n\r\n";
                    hint.setText(o + s + "http://xm540.com1.z0.glb.clouddn.com/" + key);
                }
            }, new UploadOptions(null, "test-type", true, null, null));
        }
    }
}
```
**5).常见的返回的状态码:**
使用七牛 Android sdk 的时候， 如果使用方式不正确，会返回一些对应的错误码。
具体可以参考源码：
https://github.com/qiniu/android-sdk/blob/c4cd1437aa1f2a0d68122e46b83580facdf1b74a/library/src/main/java/com/qiniu/android/http/ResponseInfo.java
```
public static final int MaliciousResponseError = -8;
public static final int LocalIOError = -7;
public static final int ZeroSizeFile = -6;
public static final int InvalidToken = -5;
public static final int InvalidArgument = -4;
public static final int InvalidFile = -3;
public static final int Cancelled = -2;
public static final int NetworkError = -1;
public static final int TimedOut = -1001;
public static final int UnknownHost = -1003;
public static final int CannotConnectToHost = -1004;
public static final int NetworkConnectionLost = -1005;
```

**6).关于混淆配置:**

混淆处理 对七牛的SDK不需要做特殊混淆处理，混淆时将七牛相关的包都排除就可以了。

在Android Studio中，混淆配置在 proguard-rules.pro 里面加上下面几行混淆代码就行：
```
-keep class com.qiniu.**{*;}
-keep class com.qiniu.**{public <init>();}
-ignorewarnings
```
注意：-ignorewarnings这个也是必须加的，如果不加这个编译的时候可能是可以通过的，但是release的时候还是会出现错误。

对于Eeclipse中也是一样的，在proguard-project.txt 文件附件同样的排除代码就可以了
```
-keep class com.qiniu.**{*;}
-keep class com.qiniu.**{public <init>();}
-ignorewarnings
```

**7).为什么进度会在95% 停很久:**
因为上传进度是用sdk写入socket的 字节数/总字节数 作为进度，但写入socket不等于服务器收到并且处理完成，中间还有一段时间，如果只是用字节数就会出现更怪异的情况，在100% 停留很久，所以综合考虑就使用了 95%这个值.

**8).如何对文件名字做模糊查询:**
如果前缀查询满足不了需求，想做多维度的查询，比如日期，userid, 文件名中的字段进行查询，可以通过开通Pandora 日志查询服务来满足。下面的例子里面需要在工作流上创建key, user, etag, mime, 四个字段的repo, 具体客户端做法如下，在上传结束后，再把结果打点到pandora 服务
```java
import com.qiniu.android.storage.UploadManager;
import com.qiniu.android.bigdata.pipeline.Pipeline;
...
    String token = "从服务端SDK获取";
    UploadManager uploadManager = new UploadManager();
    String pipelineToken = "从服务端获取 或者 生成一个长时间的token";
    Pipeline pipe = new Pipeline();
    uploadManager.put("Hello, World!".getBytes(), "hello", token,
    new UpCompletionHandler() {
        @Override
        public void complete(String key, ResponseInfo info, JSONObject response) {
            Map<String, Object> inf = new HashMap<String, Object>();
            inf.put("key", key);
            inf.put("user", "userid");
            inf.put("etag", resp.getString("hash"));
            inf.put("mime", resp.getString("mimeType"));
            pipe.pump("keysearchRepo", inf, pipelineToken, new Pipeline.PumpCompleteHandler() {
                @Override
                public void complete(ResponseInfo inf2) {
                    ...
                }
            });
        }
    }, null);
...
```

**9).如何理解上传返回 code :**
详情 [code 注释说明](https://github.com/qiniu/android-sdk/blob/master/library/src/main/java/com/qiniu/android/http/ResponseInfo.java)

## 代码贡献

详情参考[代码提交指南](https://github.com/qiniu/android-sdk/blob/master/CONTRIBUTING.md)。

## 贡献记录

- [所有贡献者](https://github.com/qiniu/android-sdk/contributors)

## 联系我们

- 如果需要帮助，请提交工单（在portal右侧点击咨询和建议提交工单，或者直接向 support@qiniu.com 发送邮件）
- 如果有什么问题，可以到问答社区提问，[问答社区](http://qiniu.segmentfault.com/)
- 更详细的文档，见[官方文档站](http://developer.qiniu.com/)
- 如果发现了bug， 欢迎提交 [issue](https://github.com/qiniu/android-sdk/issues)
- 如果有功能需求，欢迎提交 [issue](https://github.com/qiniu/android-sdk/issues)
- 如果要提交代码，欢迎提交 pull request
- 欢迎关注我们的[微信](http://www.qiniu.com/#weixin) [微博](http://weibo.com/qiniutek)，及时获取动态信息。

## 代码许可

The MIT License (MIT).详情见 [License文件](https://github.com/qiniu/android-sdk/blob/master/LICENSE).


# Presto

Presto is a distributed SQL query engine for big data.

See the [Presto installation documentation](https://prestodb.github.io/docs/current/installation) for deployment instructions.

See the [Presto documentation](https://prestodb.github.io/docs/current/) for general documentation.

## Mission and Architecture

See [PrestoDB: Mission and Architecture](ARCHITECTURE.md).

## Requirements

* Mac OS X or Linux
* Java 8 Update 151 or higher (8u151+), 64-bit. Both Oracle JDK and OpenJDK are supported.
* Maven 3.6.1+ (for building)
* Python 2.4+ (for running with the launcher script)

Building Presto

### Overview (Java)

Presto is a standard Maven project. Simply run the following command from the project root directory:

    ./mvnw clean install

On the first build, Maven will download all the dependencies from the internet and cache them in the local repository (`~/.m2/repository`), which can take a considerable amount of time. Subsequent builds will be faster.

Presto has a comprehensive set of unit tests that can take several minutes to run. You can disable the tests when building:

    ./mvnw clean install -DskipTests

After building Presto for the first time, you can load the project into your IDE and run the server. We recommend using [IntelliJ IDEA](http://www.jetbrains.com/idea/). Because Presto is a standard Maven project, you can import it into your IDE using the root `pom.xml` file. In IntelliJ, choose Open Project from the Quick Start box or choose Open from the File menu and select the root `pom.xml` file.

After opening the project in IntelliJ, double check that the Java SDK is properly configured for the project:

* Open the File menu and select Project Structure
* In the SDKs section, ensure that a 1.8 JDK is selected (create one if none exist)
* In the Project section, ensure the Project language level is set to 8.0 as Presto makes use of several Java 8 language features

Presto comes with sample configuration that should work out-of-the-box for development. Use the following options to create a run configuration:

* Main Class: `com.facebook.presto.server.PrestoServer`
* VM Options: `-ea -XX:+UseG1GC -XX:G1HeapRegionSize=32M -XX:+UseGCOverheadLimit -XX:+ExplicitGCInvokesConcurrent -Xmx2G -Dconfig=etc/config.properties -Dlog.levels-file=etc/log.properties`
* Working directory: `$MODULE_WORKING_DIR$` or `$MODULE_DIR$`(Depends your version of IntelliJ)
* Use classpath of module: `presto-main`

The working directory should be the `presto-main` subdirectory. In IntelliJ, using `$MODULE_DIR$` accomplishes this automatically.

Additionally, the Hive plugin must be configured with location of your Hive metastore Thrift service. Add the following to the list of VM options, replacing `localhost:9083` with the correct host and port (or use the below value if you do not have a Hive metastore):

    -Dhive.metastore.uri=thrift://localhost:9083

### Using SOCKS for Hive or HDFS

If your Hive metastore or HDFS cluster is not directly accessible to your local machine, you can use SSH port forwarding to access it. Setup a dynamic SOCKS proxy with SSH listening on local port 1080:

    ssh -v -N -D 1080 server

Then add the following to the list of VM options:

    -Dhive.metastore.thrift.client.socks-proxy=localhost:1080

### Running the CLI

Start the CLI to connect to the server and run SQL queries:

    presto-cli/target/presto-cli-*-executable.jar

Run a query to see the nodes in the cluster:

    SELECT * FROM system.runtime.nodes;

In the sample configuration, the Hive connector is mounted in the `hive` catalog, so you can run the following queries to show the tables in the Hive database `default`:

    SHOW TABLES FROM hive.default;

### Building the Documentation

To build the Presto docs, see the [docs README](presto-docs/README.md).

### Building the Presto Console

The Presto Console is composed of several React components and is written in JSX and ES6. This
source code is stored in the `presto-ui/` module. The compilation process generates
browser-compatible javascript which is added as JAR resources during the maven build. When the
resource JAR is included on the classpath of Presto coordinator, it will be able to serve the
resources.

None of the Java code relies on the Presto UI project being compiled, so it is possible to exclude
this UI when building Presto. It can be excluded by disabling the `ui` maven profile with `-P \!ui`:

    ./mvnw clean install -P \!ui

You must have [Node.js](https://nodejs.org/en/download/) and [Yarn](https://yarnpkg.com/en/) installed to build the UI. When using  Maven to build
the project, Node and yarn are installed in the `presto-ui/target` folder. Add the node and yarn
executables to the `PATH` environment variable.

To update Presto Console after making changes, run:

    yarn --cwd presto-ui/src install

If no JavaScript dependencies have changed (i.e., no changes to `package.json`), it is faster to run:

    yarn --cwd presto-ui/src run package

To simplify iteration, you can also run in `watch` mode, which automatically re-compiles when
changes to source files are detected:

    yarn --cwd presto-ui/src run watch

To iterate quickly, simply re-build the project in IntelliJ after packaging is complete. Project
resources will be hot-reloaded and changes are reflected on browser refresh.

## Presto native and Velox

[Presto native](https://github.com/prestodb/presto/tree/master/presto-native-execution) is a C++ rewrite of Presto worker. [Presto native](https://github.com/prestodb/presto/tree/master/presto-native-execution) uses [Velox](https://github.com/facebookincubator/velox) as its primary engine to run presto workloads.

[Velox](https://github.com/facebookincubator/velox) is a C++ database library which provides reusable, extensible, and high-performance data processing components.

Check out [building instructions](https://github.com/prestodb/presto/tree/master/presto-native-execution#building) to get started.

## Contributing!

Please refer to the [contribution guidelines](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md) to get started.

## Questions?

[Please join our Slack channel and ask in `#dev`](https://communityinviter.com/apps/prestodb/prestodb).

## License

By contributing to Presto, you agree that your contributions will be licensed under the [Apache License Version 2.0 (APLv2)](LICENSE).


![libGDX Logo](libgdx_logo.svg)

[![GitHub Actions Build Status](https://img.shields.io/github/actions/workflow/status/libgdx/libgdx/build-publish.yml?branch=master&label=GitHub%20Actions)](https://github.com/libgdx/libgdx/actions?query=workflow%3A%22Build+and+Publish%22)

[![Latest Version](https://img.shields.io/nexus/r/com.badlogicgames.gdx/gdx?nexusVersion=2&server=https%3A%2F%2Foss.sonatype.org&label=Version)](https://search.maven.org/artifact/com.badlogicgames.gdx/gdx)
[![Snapshots](https://img.shields.io/nexus/s/com.badlogicgames.gdx/gdx?server=https%3A%2F%2Foss.sonatype.org&label=Snapshots)](https://oss.sonatype.org/#nexus-search;gav~com.badlogicgames.gdx~gdx~~~~kw,versionexpand)

[![Discord Chat](https://img.shields.io/discord/348229412858101762?logo=discord)](https://libgdx.com/community/discord/)

## Cross-platform Game Development Framework
**[libGDX](https://libgdx.com) is a cross-platform Java game development framework based on OpenGL (ES), designed for Windows, Linux, macOS, Android, web browsers, and iOS.** It provides a robust and well-established environment for rapid prototyping and iterative development. Unlike other frameworks, libGDX does not impose a specific design or coding style, allowing you the freedom to create games according to your preferences.

## Open Source, Feature Packed, and Fostering a Large Third-Party Ecosystem
libGDX is released under the [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0.html), offering unrestricted usage in both commercial and non-commercial projects. While not mandatory, we appreciate any credit given to libGDX when you release a game or app using it. Check out our [showcase](https://libgdx.com/showcase/) for a selection of popular libGDX-powered games. With libGDX, you gain access to a comprehensive set of tools and features to develop multi-platform 2D and 3D games using Java.

Moreover, libGDX boasts a vibrant third-party ecosystem, with numerous [tools](https://libgdx.com/dev/tools/) and libraries that streamline development tasks. Explore the [awesome-libgdx](https://github.com/rafaskb/awesome-libgdx#readme) repository for a curated list of libGDX-centered libraries, serving as an excellent starting point for newcomers in the libGDX community.

![](https://libgdx.com/assets/images/index_showcase/game0.png)
###### An example game created with libGDX: [Pathway](https://store.steampowered.com/app/546430/Pathway/) by Robotality. Discover more captivating games in our [Showcase](https://libgdx.com/showcase/).

## Getting Started with libGDX / Documentation
Thanks to Gradle, you can easily set up libGDX without the need to download the framework itself. Your favorite build tool can handle everything for you. Additionally, we offer a convenient [setup tool](https://libgdx.com/dev/#how-to-get-started-with-libgdx) that automates project creation and downloads all the necessary components. Check out our **[website](https://libgdx.com/wiki/start/setup)** for instructions on getting started or refer to our comprehensive **[wiki](https://libgdx.com/wiki/)**.

- [Creating a libGDX Project](https://libgdx.com/wiki/start/setup)
- [Building a Simple Game](https://libgdx.com/wiki/start/a-simple-game)
- [Tutorials & Demos](https://libgdx.com/wiki/start/demos-and-tutorials)

We provide the libGDX [javadocs](https://javadoc.io/doc/com.badlogicgames.gdx) online for easy reference. Additionally, the javadocs are bundled with every libGDX distribution, ensuring smooth integration with your preferred IDE.

## Community & Contribution
Stay up to date with the **latest libGDX news** by following our [blog](https://libgdx.com/news/). For engaging discussions and support, join our official [libGDX Discord](https://libgdx.com/community/discord/).

### Reporting Issues
Use the **[Issue Tracker](https://github.com/libgdx/libgdx/issues)** here on GitHub to report any issues you encounter. Before submitting, please read our [Getting Help](https://libgdx.com/wiki/articles/getting-help) guide, which walks you through the process of reporting an issue effectively.

### Contributing to the Codebase
libGDX benefits greatly from contributions made by our dedicated developer community. We appreciate any assistance in making libGDX even better. Check out the [CONTRIBUTING.md](https://github.com/libgdx/libgdx/blob/master/.github/CONTRIBUTING.md) file for details on how to contribute. Note that contributing involves working directly with libGDX's source code, a process that regular users do not typically undertake. Refer to the [Working with the Source](https://libgdx.com/dev/from-source/) article for guidance.

You can also support our infrastructure (build server, web server, test devices) by contributing financially through our [Patreon](https://patreon.com/libgdx)!


![Mekanism Logo](logo.png)

# Mekanism for Minecraft 1.21 #

Mekanism is an independent Minecraft add-on featuring high-tech machinery that can be used to create powerful tools,
armor, and weapons. You can find more detail on the features on the [**Official Wiki**](https://wiki.aidancbrady.com/wiki/Mekanism).
With features ranging from jetpacks and balloons to factories and energy cubes, the mod does not have a single unifying goal.
Nevertheless, these features combine coherently to create a rich gameplay experience that players will enjoy.

Mekanism uses a tier-based system to organize the majority of its core features, like energy cubes and factories.
There are four tiers: basic, advanced, elite, and ultimate. Players can upgrade their components to the next tier
by placing each component in a crafting grid and surrounding it with the necessary resources for the upgrade or in
world by using tier installers.

After using Mekanism for a while, players can obtain a near-indestructible suit of Refined Obsidian Armor, receive five
ingots for each ore mined, fly with hydrogen-powered jetpacks, and have cute robotic friends following them around while they mine. :)

# Alpha Status #

Mekanism for 1.21 is currently in an alpha state. There may be crashes or game-breaking bugs, as well as,
the potential for us making breaking changes where APIs may change slightly or how data is saved to the world
changes. For this reason we do not recommend including Mekanism in any "large" packs that players may expect
things to work properly/upgrade safely from one version to the next.

We have not yet had the chance to go through and fully integrate with all of vanilla's new features,
recipes, blocks, entities, or even things like the tickrate command. Additionally, there is a handful
of things that we haven't finished porting yet.

## Known Bugs/Things that aren't done being ported yet ##
- Options in the Module Tweaker that have side effects don't currently have those side effects displayed
- When breaking and placing blocks that have fluid item input slots, they do not persist whether the item was actively being drained or whether it was being filled
- The Gravitational Modulation Unit does not currently provide flight
- Fixed (Upcoming 10.6.2): Resistive Heaters do not keep their set Energy Usage when breaking and placing again
- Fixed (Upcoming 10.6.2): Bins forget if they are locked and what they are locked too if broken and placed
- Fixed (Upcoming 10.6.2): The QIO Dashboard does not persist items stored in crafting windows when broken
- Fixed (Upcoming 10.6.2): The Portable QIO Dashboard's Crafting windows do not work at all. DO NOT TRY TO USE THEM
- Probably many more things as we have done barely any testing so far

## Configuration ##
- The GitHub Wiki docs on the json recipe syntax has not been updated to the changes we have made yet.

## API ##
There are no more planned breaking changes to the API, but that doesn't mean we won't take advantage of it being alpha to make breaks if it is needed in order to implement other missing things properly.

# Discord #

Mekanism has a [discord server](https://discord.gg/nmSjMGc) where you can chat with other Mekanism users and the developers. Join us!

# Translating #

If you would like to help translate Mekanism, you can do so through [Crowdin](https://crowdin.com/project/mekanism).

# License #

Mekanism is licensed under the MIT license. You may use it in modpacks, reviews, or any other form as long as you abide by the terms below.

Copyright 2017-2024 Aidan C. Brady

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# Maven #
Mekanism v10+ is also available via [ModMaven](https://modmaven.dev/) for developers wishing to make use of our API. Big thanks to K4Unl for hosting.

Update your `build.gradle` file to include the following:

```groovy
repositories {
    maven { url 'https://modmaven.dev/' }
}

dependencies {
    compileOnly "mekanism:Mekanism:${mekanism_version}:api"

    // If you want to test/use Mekanism & its modules during `runClient` invocation, use the following
    runtimeOnly fg.deobf("mekanism:Mekanism:${mekanism_version}")// Mekanism
    runtimeOnly fg.deobf("mekanism:Mekanism:${mekanism_version}:additions")// Mekanism: Additions
    runtimeOnly fg.deobf("mekanism:Mekanism:${mekanism_version}:generators")// Mekanism: Generators
    runtimeOnly fg.deobf("mekanism:Mekanism:${mekanism_version}:tools")// Mekanism: Tools
}
```

Add the following to your `gradle.properties` file (see [Maven](https://modmaven.dev/mekanism/Mekanism/) for the list of available versions):

```properties
mekanism_version=1.21-10.6.0.44
```

# Credits #

  * [aidancbrady](https://twitter.com/aidancbrady) - [Patreon](https://www.patreon.com/user?u=260704)
  * thommy101
  * [thiakil](https://twitter.com/thiakil)
  * [pupnewfster](https://twitter.com/pupnewfster) - [Patreon](https://www.patreon.com/pupnewfster), [Ko-fi](https://ko-fi.com/pupnewfster)
  * dizzyd
  * unpairedbracket
  * [CyanideX](https://twitter.com/theCyanideX) (artwork)
  * [Ridanisaurus](https://twitter.com/Ridanisaurus) (artwork)
  * Cheapshot (artwork)
  * Archadia (artwork)
  * micdoodle
  * Bluexin
  * JaSpr

## YourKit ##
YourKit supports open source projects with innovative and intelligent tools for monitoring and
profiling Java and .NET applications. YourKit is the creator of [YourKit Java Profiler](https://www.yourkit.com/java/profiler),
[YourKit .NET Profiler](https://www.yourkit.com/.net/profiler/) and [YourKit YouMonitor](https://www.yourkit.com/youmonitor/).
Mekanism uses YourKit for all our profiling needs!


Apache Royale Compiler
====================

    The Apache Royale Compiler compiles ActionScript 3.0 and MXML code to SWF
    or JavaScript.

    The Apache Royale Compiler was formerly known as the 'Falcon' compiler.  It was
    originally destined to be the next-generation replacement to the MXMLC compiler
    that is currently bundled with the Apache Flex SDK.  This compiler is based on the
    Adobe 'ASC 2.0' code base donated to Apache by Adobe Systems Inc.

    The compiler has been modified and extended to transpile MXML and ActionScript
    to JavaScript, and potentially other output definitions, and it is
    now being used as the compiler for the Apache Royale SDK.  Royale is a
    next-generation SDK that allows the developer to leverage MXML and ActionScript
    to build applications that not only run as a SWF, but can also be cross-compiled
    to JavaScript and run natively in a browser — or anywhere that JavaScript runs.

Getting the latest sources via git
==================================

    Getting the source code is the recommended way to get the Apache Royale Compiler.
    The compiler can also be installed by installing an Apache Royale SDK via NPM
    or by unpacking Apache Royale binary distributions available from link on our
    website at https://royale.apache.org/.

    You can always checkout the latest source via git using the following
    command:

	 git clone https://github.com/apache/royale-compiler.git royale-compiler
	 cd royale-compiler
	 git checkout develop

Building the Apache Royale Compiler
=================================

    The Apache Royale Compiler is a large project. It requires some build tools
    which must be installed prior to building the compiler and it depends on
    some external software which are downloaded as part of the build process.
    Some of these have different licenses.  See the Software Dependencies section
    for more information on the external software dependencies.

    Linux support is currently experimental has not been fully tested so you
    may run into issues.

    You can build the Apache Royale Compiler with Apache Maven or Apache Ant.

Building the Apache Royale Compiler with Apache Maven
-----------------------------------------------------

    Before building the Apache Royale Compiler with Apache Maven you must install
    the following software.

    ==================================================================================
    SOFTWARE
    ==================================================================================

    Java SDK 11 or greater (*1)

    Maven 3.8.1 or greater (*1)

    ==================================================================================

    *1) The bin directories for Maven and Java should be added to your
        PATH.

    Then run

        mvn clean install

Building the Apache Royale Compiler with Ant
----------------------------------------------

    Before building the Apache Royale Compiler with Apache Ant you must install
    the following software and set the corresponding environment variables using
    absolute file paths.  Relative file paths will result in build errors.

    ==================================================================================
    SOFTWARE                                     ENVIRONMENT VARIABLE (absolute paths)
    ==================================================================================

    Java JDK 11 or greater (*1)                            JAVA_HOME

    Ant 1.8 or greater (*1)                                ANT_HOME

    ==================================================================================

    *1) The bin directories for ANT_HOME and JAVA_HOME should be added to your
        PATH.

        On Windows, set PATH to

            PATH=%PATH%;%ANT_HOME%\bin;%JAVA_HOME%\bin

        On the Mac (bash), set PATH to

            export PATH="$PATH:$ANT_HOME/bin:$JAVA_HOME/bin"

         On Linux make sure you path include ANT_HOME and JAVA_HOME.

    Once you've done that, use

        ant main        (or just ant since the default target is main)

    to download the third-party dependencies and build the source and run
    some tests.  Since the third-party dependencies take a little while to
    download and they don't change very often, they are not cleaned with
     the regular clean target.

    To clean the build of everything other than the downloaded third-party
    dependencies use

        ant clean

    To clean the build, of everything, including the downloaded third-party
    dependencies use

        ant wipe-all (which is just thirdparty-clean followed by clean)

    To get a brief listing of all the targets type

        ant -projecthelp

Running Integration Tests
-------------------------

    The build process will run some tests.  By default, the build will not
    run feature or integration tests.  Before running some of the feature or
    integration tests you will need to set the environment variables described
    below, or set up a env.properties file with those settings.

    A template is found here: env-template.properties.

    Some tests of SWF output may use the Adobe Flash Player or Adobe AIR to
    run a SWF.  If you plan to run those tests, ensure that the folder
    containing the source code is in your Flash Player Trust files.

    ==================================================================================
    SOFTWARE                                     ENVIRONMENT VARIABLE (absolute paths)
    ==================================================================================

    Apache Royale SDK or repository (*3)         ASJS_HOME

    Adobe AIR Integration Kit (*4)               AIR_HOME

    Adobe Flash Player Content Debugger (*5)     FLASHPLAYER_DEBUGGER

    Adobe Flash Player playerglobal swcs (*6)    PLAYERGLOBAL_HOME

    Adobe Flash Player playerglobal swcs (*6)    PLAYERGLOBAL_VERSION

    Apache Flex SDK or repository (*7)           FLEX_HOME

    Apache Flex TLF source (*8)                  TLF_HOME

    ==================================================================================

    *3) This option is only required to run additional tests to verify that the compiler
        can output Royale applications that use Royale framework SWCs.

        Set the ASJS_HOME variable to the root of the Apache Royale SDK or
        royale-asjs repository.

    *4) This option is only required to run additional tests to verify that the compiler
        can output SWFs.

        The Adobe AIR integration kit for Windows can be downloaded from:
            https://airdownload.adobe.com/air/win/download/32.0/AdobeAIRSDK.zip

         The Adobe AIR integration kit for Mac can be downloaded from:
            https://airdownload.adobe.com/air/mac/download/32.0/AdobeAIRSDK.dmg

        Download the AIR SDK for your platform and unzip it. Set AIR_HOME to the
        absolute path of the AIR SDK directory.

    *5) This option is only required to run additional tests to verify that the compiler
        can output SWFs.

        The Adobe Flash Player content debugger for Windows can be downloaded from:
            https://fpdownload.macromedia.com/pub/flashplayer/updaters/32/flashplayer_32_sa_debug.exe

        The Adobe Flash Player content debugger for Mac can be downloaded from:
            https://fpdownload.macromedia.com/pub/flashplayer/updaters/32/flashplayer_32_sa_debug.dmg

        The Adobe Flash Player content debugger for Linux can be downloaded from:
            https://fpdownload.macromedia.com/pub/flashplayer/updaters/32/flash_player_sa_linux_debug.x86_64.tar.gz

        On Windows, set FLASHPLAYER_DEBUGGER to the absolute path including the
        filename of the FlashPlayerDebugger.exe. Note the filename of flash
        player debugger maybe different.
           e.g. C:\MyPath\FlashPlayerDebugger.exe

        On the Mac, set FLASHPLAYER_DEBUGGER to the absolute path of
        Flash Player Debugger.app/Contents/MacOS/Flash Player Debugger

        On Linux, set FLASHPLAYER_DEBUGGER to the absolute path of
        flashplayerdebugger

    *6) This option is only required to run additional tests to verify that the compiler
        can output SWFs.

        The Adobe Flash Player playerglobal.swc for 32.0 can be downloaded from:
            https://fpdownload.macromedia.com/get/flashplayer/updaters/32/playerglobal32_0.swc

        Use URL above to download playerglobal32_0.swc.

        Set PLAYERGLOBAL_HOME to the absolute path of the player directory (not
        including the version subdirectory). The target-player option controls
        which PLAYERGLOBAL_HOME subdirectory is used.

        Copy the target playerglobal.swc to the directory:

           frameworks/libs/player/<version.major>.<version.minor>/playerglobal.swc

        These can be used with the Apache Royale Compiler but not all have not been fully
        tested.

        Set PLAYERGLOBAL_VERSION to the version you chose.  The default is 11.1.

    *7) This option is only required to run additional tests to verify that the compiler
        can output SWFs.

        The FLEX_HOME variable should point to a folder of the flex-sdk sources.
        If you don’t provide this variable (and TLF_HOME and BLAZEDS_HOME),
        you may not be able to run all of the tests in the compiler
        and compiler-jx folders.

    *8) This option is only required to run additional tests to verify that the compiler
        can output SWFs.

        The TLF_HOME variable should point to a folder containing a folder
        named textLayout that contains a src folder of the TLF sources.
        This should be the root of the flex-tlf repository, or can be
        the frameworks/projects folder of an IDE compatible Royale SDK.

Software Dependencies
---------------------

    The Apache Royale Compiler uses third-party code that will be downloaded as
    part of the build.

    The Apache Version 2.0 license is in the LICENSE file.

    The following dependencies have licenses which are, or are compatible with,
    the Apache Version 2.0 license.  You will not be prompted to acknowledge the
    download.  Most of the jars are installed in lib/external when installed
    into an Apache Royale SDK and the lib folder in the repository working copy.

        antlr - https://repo1.maven.org/maven2/org/antlr/antlr-complete/3.5.2/antlr-3.5.2-complete.jar
        args4j - https://repo1.maven.org/maven2/args4j/args4j/2.0.28/args4j-2.0.28.jar
        commons-cli - https://repo1.maven.org/maven2/commons-cli/commons-cli/1.2/commons-cli-1.2.jar
        commons-io - https://repo1.maven.org/maven2/commons-io/commons-io/2.11.0/commons-io-2.11.0.jar
        commons-lang - https://repo1.maven.org/maven2/commons-lang/commons-lang/2.6/commons-lang-2.6.jar
        commons-lang3 - https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.jar
        commons-compress - https://repo1.maven.org/maven2/org/apache/commons/commons-compress/1.26.0/commons-compress-1.26.0.jar
        guava - https://repo1.maven.org/maven2/com/google/guava/guava/32.0.0-jre/guava-32.0.0-jre.jar
        failureaccess - https://repo1.maven.org/maven2/com/google/guava/failureaccess/1.0.2/failureaccess-1.0.2.jar
        jburg - https://repo1.maven.org/maven2/net/sourceforge/jburg/jburg/1.10.2/jburg-1.10.2.jar
        jflex - https://jflex.de/jflex-1.6.0.tar.gz
        lzma - http://www.java2s.com/Code/JarDownload/lzma/lzma-9.20.jar.zip
        Google Closure Compiler - https://github.com/google/closure-compiler/archive/v20181210.zip

    The Google Closure Compiler includes files originally from Rhino under MPL 1.1.  For
    details see:
       https://github.com/google/closure-compiler/blob/master/README.md.
    Rhino is available at:
       https://github.com/mozilla/rhino

Using the Binary Distribution
-----------------------------

    The binary artifacts produced by the Maven build are then used by Maven projects
    to build Apache Royale applications.  See the archetypes in the royale-asjs repo
    or the examples in the royale-asjs repo.

    The binaries produced by the Apache Ant build are intended to be packaged into an
    Apache Royale SDK to create Apache Royale applications via IDEs, Ant build
    scripts, or by running the compiler executables directly from the command line.

    To temporarily use a set of binary artifacts when building Apache Royale
    applications with Apache Ant, set the ROYALE_COMPILER_HOME property to the
    compiler-jx folder in the binary distribution and set ROYALE_SWF_COMPILER_HOME
    to the compiler folder in the binary distribution either via an
    environment variable or property when running Ant to build the Apache Royale
    application.

    To replace the current Royale Compiler binaries in a Apache Royale SDK,
    run the copy-compiler target from the Ant script in the Apache Royale SDK and
    set ROYALE_COMPILER_REPO to the root of the binary distribution when running
    that target.

       ant -DROYALE_COMPILER_REPO=<path to binary distribution> copy-compiler

Thanks for using Apache Royale. Enjoy!

                                          The Apache Royale Project
                                          <https://royale.apache.org>


[![Maven Central](https://img.shields.io/maven-central/v/org.owasp/dependency-check-maven.svg)](https://mvnrepository.com/artifact/org.owasp/dependency-check-maven) [![Build and Deploy Snapshot](https://github.com/jeremylong/DependencyCheck/actions/workflows/build.yml/badge.svg)](https://github.com/jeremylong/DependencyCheck/actions/workflows/build.yml) [![Coverity Scan Build Status](https://img.shields.io/coverity/scan/1654.svg)](https://scan.coverity.com/projects/dependencycheck) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/6b6021d481dc41a888c5da0d9ecf9494)](https://www.codacy.com/app/jeremylong/DependencyCheck?utm_source=github.com&utm_medium=referral&utm_content=jeremylong/DependencyCheck&utm_campaign=Badge_Grade) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/843/badge)](https://bestpractices.coreinfrastructure.org/projects/843) [![Apache 2.0 License](https://img.shields.io/badge/license-Apache%202-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0.txt)

[![Black Hat Arsenal](https://raw.githubusercontent.com/toolswatch/badges/master/arsenal/usa/2018.svg?sanitize=true)](http://www.toolswatch.org/2018/05/black-hat-arsenal-usa-2018-the-w0w-lineup/) [![Black Hat Arsenal](https://www.toolswatch.org/badges/arsenal/2015.svg)](https://www.toolswatch.org/2015/06/black-hat-arsenal-usa-2015-speakers-lineup/) [![Black Hat Arsenal](https://www.toolswatch.org/badges/arsenal/2014.svg)](https://www.toolswatch.org/2014/06/black-hat-usa-2014-arsenal-tools-speaker-list/) [![Black Hat Arsenal](https://www.toolswatch.org/badges/arsenal/2013.svg)](https://www.toolswatch.org/2013/06/announcement-blackhat-arsenal-usa-2013-selected-tools/)

# Dependency-Check

Dependency-Check is a Software Composition Analysis (SCA) tool that attempts to detect publicly disclosed vulnerabilities contained within a project's dependencies. It does this by determining if there is a Common Platform Enumeration (CPE) identifier for a given dependency. If found, it will generate a report linking to the associated CVE entries.

Documentation and links to production binary releases can be found on the [github pages](http://jeremylong.github.io/DependencyCheck/). Additionally, more information about the architecture and ways to extend dependency-check can be found on the [wiki].

## 9.0.0 Upgrade Notice

**Upgrading to 9.0.0 or later is mandatory**; previous versions of dependency-check
utilize the NVD data feeds which will be deprecated on Dec 15th, 2023. Versions
earlier then 9.0.0 are no longer supported and could fail to work after Dec 15th, 2023.

### NVD API Key Highly Recommended

With 9.0.0 dependency-check has moved from using the NVD data-feed to the NVD API.
Users of dependency-check are **highly** encouraged to obtain an NVD API Key; see https://nvd.nist.gov/developers/request-an-api-key
Without an NVD API Key dependency-check's updates will be **extremely slow**.
Please see the documentation for the cli, maven, gradle, or ant integrations on
how to set the NVD API key.

#### The NVD API Key, CI, and Rate Limiting

The NVD API has enforced rate limits. If you are using a single API KEY and
multiple builds occur you could hit the rate limit and receive 403 errors. In
a CI environment one must use a caching strategy.

### Breaking Changes

9.0.0 contains breaking changes which requires updates to the database. If using
an externally hosted database the schema will need to be updated. When using the
embedded H2 database, the schema should be upgraded automatically. However, if
issues arise you may need to purge the database:

- gradle: `./gradlew dependencyCheckPurge`
- maven: `mvn org.owasp:dependency-check-maven:9.0.0:purge`
- cli: `dependency-check.sh --purge`

#### Gradle build Environment

With 9.0.0 users may encounter issues with `NoSuchMethodError` exceptions due to
dependency resolution. If you encounter this issue you will need to pin some of
the transitive dependencies of dependency-check to specific versions. For example:

/buildSrc/build.gradle
```groovy
dependencies {
    constraints {
        // org.owasp.dependencycheck needs at least this version of jackson. Other plugins pull in older versions..
        add("implementation", "com.fasterxml.jackson:jackson-bom:2.16.1")

        // org.owasp.dependencycheck needs these versions. Other plugins pull in older versions..
        add("implementation", "org.apache.commons:commons-lang3:3.14.0")
        add("implementation", "org.apache.commons:commons-text:1.11.0")
    }
}
```

## Requirements

### Java Version

Minimum Java Version: Java 8 update 251

While dependency-check 9.0.0 and higher will still run on Java 8 - the update version
must be higher then 251.

### Internet Access

OWASP dependency-check requires access to several externally hosted resources.
For more information see [Internet Access Required](https://jeremylong.github.io/DependencyCheck/data/index.html).

### Build Tools

In order to analyze some technology stacks dependency-check may require other
development tools to be installed. Some of the analysis listed below may be
experimental and require the experimental analyzers to be enabled.

1. To analyze .NET Assemblies the dotnet 6 run time or SDK must be installed.
   - Assemblies targeting other run times can be analyzed - but 6 is required to run the analysis.
2. If analyzing GoLang projects `go` must be installed.
3. The analysis of `Elixir` projects requires `mix_audit`.
4. The analysis of `npm`, `pnpm`, and `yarn` projects requires `npm`, `pnpm`, or `yarn` to be installed.
   - The analysis performed utilize the respective `audit` feature of each.
5. The analysis of Ruby is a wrapper around `bundle-audit`, which must be installed.

## Current Releases

### Jenkins Plugin

For instructions on the use of the Jenkins plugin please see the [OWASP Dependency-Check Plugin page](https://wiki.jenkins-ci.org/display/JENKINS/OWASP+Dependency-Check+Plugin).

### Command Line

More detailed instructions can be found on the
[dependency-check github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-cli/).
The latest CLI can be downloaded from github in the [releases section](https://github.com/jeremylong/DependencyCheck/releases).

Downloading the latest release:
```
$ VERSION=$(curl -s https://jeremylong.github.io/DependencyCheck/current.txt)
$ curl -Ls "https://github.com/jeremylong/DependencyCheck/releases/download/v$VERSION/dependency-check-$VERSION-release.zip" --output dependency-check.zip
```

On *nix
```
$ ./bin/dependency-check.sh -h
$ ./bin/dependency-check.sh --out . --scan [path to jar files to be scanned]
```
On Windows
```
> .\bin\dependency-check.bat -h
> .\bin\dependency-check.bat --out . --scan [path to jar files to be scanned]
```
On Mac with [Homebrew](http://brew.sh)
Note - homebrew users upgrading from 5.x to 6.0.0 will need to run `dependency-check.sh --purge`.
```
$ brew update && brew install dependency-check
$ dependency-check -h
$ dependency-check --out . --scan [path to jar files to be scanned]
```

### Maven Plugin

More detailed instructions can be found on the [dependency-check-maven github pages](http://jeremylong.github.io/DependencyCheck/dependency-check-maven).
By default, the plugin is tied to the `verify` phase (i.e. `mvn verify`). Alternatively,
one can directly invoke the plugin via `mvn org.owasp:dependency-check-maven:check`.

The dependency-check plugin can be configured using the following:

```xml
<project>
    <build>
        <plugins>
            ...
            <plugin>
              <groupId>org.owasp</groupId>
              <artifactId>dependency-check-maven</artifactId>
              <executions>
                  <execution>
                      <goals>
                          <goal>check</goal>
                      </goals>
                  </execution>
              </executions>
            </plugin>
            ...
        </plugins>
        ...
    </build>
    ...
</project>
```

### Gradle Plugin

For instructions on the use of the Gradle Plugin, please see the [dependency-check-gradle github page](http://jeremylong.github.io/DependencyCheck/dependency-check-gradle).

### Ant Task

For instructions on the use of the Ant Task, please see the [dependency-check-ant github page](http://jeremylong.github.io/DependencyCheck/dependency-check-ant).

## Development Prerequisites

For installation to pass, you must have the following components installed:
* Java: `java -version` 1.8
* Maven: `mvn -version` 3.5.0 and higher

Tests cases require:
* dotnet core version 6.0
* Go: `go version` 1.12 and higher
* Ruby [bundler-audit](https://github.com/rubysec/bundler-audit#install)
* [Yarn](https://classic.yarnpkg.com/en/docs/install/)
* [pnpm](https://pnpm.io/installation)

## Development Usage

The following instructions outline how to compile and use the current snapshot. While every intention is to maintain a stable snapshot it is recommended
that the release versions listed above be used.

The repository has some large files due to test resources. The team has tried to clean up the history as much as possible.
However, it is recommended that you perform a shallow clone to save yourself time:

```bash
git clone --depth 1 https://github.com/jeremylong/DependencyCheck.git
```

On *nix
```
$ mvn -s settings.xml install
$ ./cli/target/release/bin/dependency-check.sh -h
$ ./cli/target/release/bin/dependency-check.sh --out . --scan ./src/test/resources
```
On Windows
```
> mvn -s settings.xml install
> .\cli\target\release\bin\dependency-check.bat -h
> .\cli\target\release\bin\dependency-check.bat --out . --scan ./src/test/resources
```

Then load the resulting 'dependency-check-report.html' into your favorite browser.

#### Building without running tests
To speed up your turnaround cycle times, you can also compile without running the tests each time:
`mvn -s settings.xml install -DskipTests=true`

Please remember to at least run the tests once before opening the PR. :)

### IntelliJ Idea
To be able to debug your tests in IntelliJ Idea, you can introduce a maven configuration that executes your test and enables debugging with breakpoints etc.
Basically, you do what´s described in https://www.jetbrains.com/help/idea/work-with-tests-in-maven.html#run_single_test and set the `forkCount` to 0, otherwise debugging won´t work.

Step by step:
- `Run -> Edit Configurations`
- `+ (Add new configuration) -> Maven`
- Give the Configuration a name, e.g. `Run tests`
- Choose working directory, e.g. `core`
- In `command line`, enter `-DforkCount=0 -f pom.xml -s ../settings.xml test`
- Press `OK`
- `Run -> Debug`, then choose the newly created run configuration

IntelliJ will now execute the test run for the `core` subproject with enabled debugging. Breakpoints set anywhere in code should work.

#### Only test one function or one class
If you would like to speed up your turnaround cycle times, you can also just test one function or one test class.
This works by adding `-Dtest=MyTestClass` or `-Dtest=MyTestClass#myTestFunction` to the run configuration. The complete command line in the run configuration then would be:

`-Dtest=MyTestClass#myTestFunction -DforkCount=0 -f pom.xml -s ../settings.xml test`

### Docker

In the following example it is assumed that the source to be checked is in the current working directory and the reports will be written to `$(pwd)/odc-reports`. Persistent data and cache directories are used, allowing you to destroy the container after running.

For Linux:
```sh
#!/bin/sh

DC_VERSION="latest"
DC_DIRECTORY=$HOME/OWASP-Dependency-Check
DC_PROJECT="dependency-check scan: $(pwd)"
DATA_DIRECTORY="$DC_DIRECTORY/data"
CACHE_DIRECTORY="$DC_DIRECTORY/data/cache"

if [ ! -d "$DATA_DIRECTORY" ]; then
    echo "Initially creating persistent directory: $DATA_DIRECTORY"
    mkdir -p "$DATA_DIRECTORY"
fi
if [ ! -d "$CACHE_DIRECTORY" ]; then
    echo "Initially creating persistent directory: $CACHE_DIRECTORY"
    mkdir -p "$CACHE_DIRECTORY"
fi

# Make sure we are using the latest version
docker pull owasp/dependency-check:$DC_VERSION

docker run --rm \
    -e user=$USER \
    -u $(id -u ${USER}):$(id -g ${USER}) \
    --volume $(pwd):/src:z \
    --volume "$DATA_DIRECTORY":/usr/share/dependency-check/data:z \
    --volume $(pwd)/odc-reports:/report:z \
    owasp/dependency-check:$DC_VERSION \
    --scan /src \
    --format "ALL" \
    --project "$DC_PROJECT" \
    --out /report
    # Use suppression like this: (where /src == $pwd)
    # --suppression "/src/security/dependency-check-suppression.xml"
```

For Windows:
```bat
@echo off

set DC_VERSION="latest"
set DC_DIRECTORY=%USERPROFILE%\OWASP-Dependency-Check
SET DC_PROJECT="dependency-check scan: %CD%"
set DATA_DIRECTORY="%DC_DIRECTORY%\data"
set CACHE_DIRECTORY="%DC_DIRECTORY%\data\cache"

IF NOT EXIST %DATA_DIRECTORY% (
    echo Initially creating persistent directory: %DATA_DIRECTORY%
    mkdir %DATA_DIRECTORY%
)
IF NOT EXIST %CACHE_DIRECTORY% (
    echo Initially creating persistent directory: %CACHE_DIRECTORY%
    mkdir %CACHE_DIRECTORY%
)

rem Make sure we are using the latest version
docker pull owasp/dependency-check:%DC_VERSION%

docker run --rm ^
    --volume %CD%:/src ^
    --volume %DATA_DIRECTORY%:/usr/share/dependency-check/data ^
    --volume %CD%/odc-reports:/report ^
    owasp/dependency-check:%DC_VERSION% ^
    --scan /src ^
    --format "ALL" ^
    --project "%DC_PROJECT%" ^
    --out /report
    rem Use suppression like this: (where /src == %CD%)
    rem --suppression "/src/security/dependency-check-suppression.xml"
```

Building From Source
--------------------

To build dependency-check (using Java 8) run the command:

```
mvn -s settings.xml install
```

Running dependency-check on dependency-check
--------------------------------------------

Dependency-check references several vulnerable dependencies that are never used
except as test resources. All of these optional test dependencies are included in
the `test-dependencies` profile. To run dependency-check against itself simple
exclude the `test-dependencies` profile:

```shell
mvn org.owasp:dependency-check-maven:aggregate -P-test-dependencies -DskipProvidedScope=true
```

Building the documentation
--------------------------

The documentation on the [github pages](http://jeremylong.github.io/DependencyCheck/) is generated from this repository:

    mvn -s settings.xml site  site:staging

Once done, point your browser to `./target/staging/index.html`.

Building The Docker Image
-------------------------
To build dependency-check docker image run the command:

```
mvn -s settings.xml install
./build-docker.sh
```

License
-------

Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [LICENSE.txt](https://raw.githubusercontent.com/jeremylong/DependencyCheck/main/LICENSE.txt) file for the full license.

Dependency-Check makes use of several other open source libraries. Please see the [NOTICE.txt][notices] file for more information.

This product uses the NVD API but is not endorsed or certified by the NVD.

Copyright (c) 2012-2024 Jeremy Long. All Rights Reserved.

  [wiki]: https://github.com/jeremylong/DependencyCheck/wiki
  [notices]: https://github.com/jeremylong/DependencyCheck/blob/main/NOTICE.txt


# Apache Drill

[![Build Status](https://github.com/apache/drill/workflows/Github%20CI/badge.svg)](https://github.com/apache/drill/actions)
[![Artifact](https://img.shields.io/maven-central/v/org.apache.drill/distribution.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.apache.drill%22%20AND%20a%3A%22distribution%22)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
[![Stack Overflow](https://img.shields.io/:stack%20overflow-apache--drill-brightgreen.svg)](http://stackoverflow.com/questions/tagged/apache-drill)
[![Join Drill Slack](https://img.shields.io/badge/slack-open-e01563.svg)](http://apache-drill.slack.com "Join our Slack community")

Apache Drill is a distributed MPP query layer that supports SQL and alternative query languages against NoSQL and Hadoop data storage systems.  It was inspired in part by [Google's Dremel](http://research.google.com/pubs/pub36632.html).

## Developers

Please read [Environment.md](docs/dev/Environment.md) for setting up and running Apache Drill. For complete developer documentation see [DevDocs.md](docs/dev/DevDocs.md).

## More Information
Please see the [Apache Drill Website](http://drill.apache.org/) or the [Apache Drill Documentation](http://drill.apache.org/docs/) for more information including:

 * Remote Execution Installation Instructions
 * [Running Drill on Docker instructions](https://drill.apache.org/docs/running-drill-on-docker/)
 * Information about how to submit logical and distributed physical plans
 * More example queries and sample data
 * Find out ways to be involved or discuss Drill

## Join the community!
Apache Drill is an Apache Foundation project and is seeking all types of users and contributions.
Please say hello on the [Apache Drill mailing list](http://drill.apache.org/mailinglists/).You can also join our [Google Hangouts](http://drill.apache.org/community-resources/)
or [join](https://bit.ly/2VM0XS8) our [Slack Channel](https://join.slack.com/t/apache-drill/shared_invite/enQtNTQ4MjM1MDA3MzQ2LTJlYmUxMTRkMmUwYmQ2NTllYmFmMjU4MDk0NjYwZjBmYjg0MDZmOTE2ZDg0ZjBlYmI3Yjc4Y2I2NTQyNGVlZTc) if you need help with using or developing Apache Drill (more information can be found on [Apache Drill website](http://drill.apache.org/)).

## Export Control
This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See <http://www.wassenaar.org/> for more information.
The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms. The form and manner of this Apache Software Foundation distribution makes it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code.
The following provides more details on the included cryptographic software:
 Java SE Security packages are used to provide support for authentication, authorization and secure sockets communication. The Jetty Web Server is used to provide communication via HTTPS. The Cyrus SASL libraries, Kerberos Libraries and OpenSSL Libraries are used to provide SASL based authentication and SSL communication.


# Open eHealth Integration Platform

![Build Status](https://github.com/oehf/ipf/actions/workflows/build.yml/badge.svg)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.openehealth.ipf/ipf/badge.svg)](http://mvnrepository.com/artifact/org.openehealth.ipf)

## IPF Overview

The eHealth Integration Framework (IPF) is an extension of the [Apache Camel](https://camel.apache.org/) routing and mediation engine and comes with
comprehensive support for message processing and connecting information systems in the healthcare sector.
It is available under the Apache License version 2.0.

IPF focuses on a domain-specific language (DSL) to implement Enterprise Integration Patterns (EIPs) in integration solutions.
IPF is based on the Java and [Groovy](https://groovy-lang.org/) programming languages for application development and for designing project-specific DSLs.

IPF provides highl-level building blocks for implementing IHE profiles such as [XDS](https://profiles.ihe.net/ITI/TF/Volume1/ch-10.html), [PIX](https://profiles.ihe.net/ITI/TF/Volume1/ch-5.html), [PDQ](https://profiles.ihe.net/ITI/TF/Volume1/ch-8.html) or [XCPD](https://profiles.ihe.net/ITI/TF/Volume1/ch-27.html).
Other supported standards are HL7v2 and HL7v3 (CDA and CCD) for which IPF provides domain-specific languages (DSLs) for
creation, parsing, rendering, navigation and modification.

## Documentation

The IPF documentation is available via [Github Pages](https://oehf.github.io/ipf-docs). This is a revamp of the existing
documentation that is still [available here](http://oehf.github.io/ipf), with some content yet to be written.

There's also a somewhat outdated [Introductory article](https://dzone.com/articles/introduction-open-ehealth).

## Mailing Lists

* [ipf-dev](https://groups.google.com/group/ipf-dev)
* [ipf-user](https://groups.google.com/group/ipf-user)


snappy-java
[![Build Status](https://travis-ci.org/xerial/snappy-java.svg?branch=master)](https://travis-ci.org/xerial/snappy-java)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.xerial.snappy/snappy-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.xerial.snappy/snappy-java/)
[![Javadoc](https://javadoc.io/badge2/org.xerial.snappy/snappy-java/javadoc.svg)](https://javadoc.io/doc/org.xerial.snappy/snappy-java)
===
snappy-java is a Java port of the [snappy](https://github.com/google/snappy), a fast C++ compresser/decompresser developed by Google.

## Features
  * Fast compression/decompression around 200~400MB/sec.
  * Less memory usage. SnappyOutputStream uses only 32KB+ in default.
  * JNI-based implementation to achieve comparable performance to the native C++ version.
     * Although snappy-java uses JNI, it can be used safely with multiple class loaders (e.g. Tomcat, etc.).
  * Compression/decompression of Java primitive arrays (`float[]`, `double[]`, `int[]`, `short[]`, `long[]`, etc.)
     * To improve the compression ratios of these arrays, you can use a fast data-rearrangement implementation ([`BitShuffle`](https://oss.sonatype.org/service/local/repositories/releases/archive/org/xerial/snappy/snappy-java/1.1.8/snappy-java-1.1.8-javadoc.jar/!/org/xerial/snappy/BitShuffle.html)) before compression
  * Portable across various operating systems; Snappy-java contains native libraries built for Window/Mac/Linux, etc. snappy-java loads one of these libraries according to your machine environment (It looks system properties, `os.name` and `os.arch`).
  * Simple usage. Add the snappy-java-(version).jar file to your classpath. Then call compression/decompression methods in `org.xerial.snappy.Snappy`.
  * [Framing-format support](https://github.com/google/snappy/blob/master/framing_format.txt) (Since 1.1.0 version)
  * OSGi support
  * [Apache License Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). Free for both commercial and non-commercial use.

## Performance
  * Snappy's main target is very high-speed compression/decompression with reasonable compression size. So the compression ratio of snappy-java is modest and about the same as `LZF` (ranging 20%-100% according to the dataset).

  * Here are some [benchmark results](https://github.com/ning/jvm-compressor-benchmark/wiki), comparing
 snappy-java and the other compressors
 `LZO-java`/`LZF`/`QuickLZ`/`Gzip`/`Bzip2`. Thanks [Tatu Saloranta @cotowncoder](http://twitter.com/#!/cowtowncoder) for providing the benchmark suite.
  * The benchmark result indicates snappy-java is the fastest compressor/decompressor in Java: https://ning.github.io/jvm-compressor-benchmark/results/canterbury-roundtrip-2011-07-28/index.html
 * The decompression speed is twice as fast as the others: https://ning.github.io/jvm-compressor-benchmark/results/canterbury-uncompress-2011-07-28/index.html

## Download

[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.xerial.snappy/snappy-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.xerial.snappy/snappy-java/)
[![Javadoc](https://javadoc.io/badge2/org.xerial.snappy/snappy-java/javadoc.svg)](https://javadoc.io/doc/org.xerial.snappy/snappy-java)

 * [Release Notes](Milestone.md)

The current stable version is available from here:
  * Release version: https://repo1.maven.org/maven2/org/xerial/snappy/snappy-java/
  * Snapshot version (the latest beta version): https://oss.sonatype.org/content/repositories/snapshots/org/xerial/snappy/snappy-java/

### Using with Maven

Snappy-java is available from Maven's central repository. Add the following dependency to your pom.xml:

    <dependency>
      <groupId>org.xerial.snappy</groupId>
      <artifactId>snappy-java</artifactId>
      <version>(version)</version>
      <type>jar</type>
      <scope>compile</scope>
    </dependency>

### Using with sbt

```
libraryDependencies += "org.xerial.snappy" % "snappy-java" % "(version)"
```

## Usage
First, import `org.xerial.snapy.Snappy` in your Java code:

```java
import org.xerial.snappy.Snappy;
```

Then use `Snappy.compress(byte[])` and `Snappy.uncompress(byte[])`:

```java
String input = "Hello snappy-java! Snappy-java is a JNI-based wrapper of "
     + "Snappy, a fast compresser/decompresser.";
byte[] compressed = Snappy.compress(input.getBytes("UTF-8"));
byte[] uncompressed = Snappy.uncompress(compressed);

String result = new String(uncompressed, "UTF-8");
System.out.println(result);
```

In addition, high-level methods (`Snappy.compress(String)`, `Snappy.compress(float[] ..)` etc. ) and low-level ones (e.g. `Snappy.rawCompress(.. )`,  `Snappy.rawUncompress(..)`, etc.), which minimize memory copies, can be used.

### Stream-based API
Stream-based compressor/decompressor `SnappyOutputStream`/`SnappyInputStream` are also available for reading/writing large data sets. `SnappyFramedOutputStream`/`SnappyFramedInputStream` can be used for the [framing format](https://github.com/google/snappy/blob/master/framing_format.txt).

 * See also [Javadoc API](https://oss.sonatype.org/service/local/repositories/releases/archive/org/xerial/snappy/snappy-java/1.1.3-M1/snappy-java-1.1.3-M1-javadoc.jar/!/index.html)

#### Compatibility Notes

The original Snappy format definition did not define a file format. It later added
a "framing" format to define a file format, but by this point major software was
already using an industry standard instead -- represented in this library by the
`SnappyOutputStream` and `SnappyInputStream` methods.

For interoperability with other libraries, check that compatible formats are used.
Note that not all libraries support all variants.

 * `SnappyOutputStream` and `SnappyInputStream` use `[magic header:16 bytes]([block size:int32][compressed data:byte array])*` format. You can read the result of `Snappy.compress` with `SnappyInputStream`, but you cannot read the compressed data generated by `SnappyOutputStream` with `Snappy.uncompress`.
 * `SnappyHadoopCompatibleOutputStream` does not emit a file header but write out the current block size as a  preemble to each block

#### Data format compatibility matrix:

| Write\Read      | `Snappy.uncompress`   | `SnappyInputStream`  | `SnappyFramedInputStream` | `org.apache.hadoop.io.compress.SnappyCodec` |
| --------------- |:-------------------:|:------------------:|:-----------------------:|:-------------------------------------------:|
| `Snappy.compress` | ok | ok | x | x |
| `SnappyOutputStream`  | x | ok | x | x |
| `SnappyFramedOutputStream` | x | x | ok | x |
| `SnappyHadoopCompatibleOutputStream` | x | x | x | ok |

### BitShuffle API (Since 1.1.3-M2)

BitShuffle is an algorithm that reorders data bits (shuffle) for efficient compression (e.g., a sequence of integers, float values, etc.). To use BitShuffle routines, import `org.xerial.snapy.BitShuffle`:

```java
import org.xerial.snappy.BitShuffle;

int[] data = new int[] {1, 3, 34, 43, 34};
byte[] shuffledByteArray = BitShuffle.shuffle(data);
byte[] compressed = Snappy.compress(shuffledByteArray);
byte[] uncompressed = Snappy.uncompress(compressed);
int[] result = BitShuffle.unshuffleIntArray(uncompress);

System.out.println(result);
```

Shuffling and unshuffling of primitive arrays (e.g., `short[]`, `long[]`,  `float[]`, `double[]`, etc.) are supported. See [Javadoc](http://static.javadoc.io/org.xerial.snappy/snappy-java/1.1.3-M1/org/xerial/snappy/BitShuffle.html) for the details.

### Setting classpath
If you have snappy-java-(VERSION).jar in the current directory, use `-classpath` option as follows:

    $ javac -classpath ".;snappy-java-(VERSION).jar" Sample.java  # in Windows
    or
    $ javac -classpath ".:snappy-java-(VERSION).jar" Sample.java  # in Mac or Linux

## Public discussion group
Post bug reports or feature request to the Issue Tracker: <https://github.com/xerial/snappy-java/issues>

Public discussion forum is here: [Xerial Public Discussion Group](http://groups.google.com/group/xerial?hl=en)

## For developers

snappy-java uses sbt (simple build tool for Scala) as a build tool. Here is a simple usage

    $ ./sbt            # enter sbt console
    > ~test            # run tests upon source code change
    > ~testOnly        # run tests that matches a given name pattern
    > publishM2        # publish jar to $HOME/.m2/repository
    > package          # create jar file
    > findbugs         # Produce findbugs report in target/findbugs
    > jacoco:cover     # Report the code coverage of tests to target/jacoco folder

If you need to see detailed debug messages, launch sbt with `-Dloglevel=debug` option:

```
$ ./sbt -Dloglevel=debug
```

For the details of sbt usage, see my blog post: [Building Java Projects with sbt](http://xerial.org/blog/2014/03/24/sbt/)

### Building from the source code

See the [build instruction](https://github.com/xerial/snappy-java/blob/master/BUILD.md). Building from the source code is an option when your OS platform and CPU architecture is not supported. To build snappy-java, you need Git, JDK (1.6 or higher), g++ compiler (mingw in Windows) etc.

    $ git clone https://github.com/xerial/snappy-java.git
    $ cd snappy-java
    $ make

When building on Solaris, use `gmake`:

    $ gmake

A file `target/snappy-java-$(version).jar` is the product additionally containing the native library built for your platform.

### Creating a new release

GitHub action [https://github.com/xerial/snappy-java/blob/master/.github/workflows/release.yml] will publish a new relase to Maven Central (Sonatype) when a new tag vX.Y.Z is pushed.

## Miscellaneous Notes

### Using snappy-java with Tomcat 6 (or higher) Web Server

Simply put the snappy-java's jar to WEB-INF/lib folder of your web application. Usual JNI-library specific problem no longer exists since snappy-java version 1.0.3 or higher can be loaded by multiple class loaders.

### Configure snappy-java using property file

Prepare org-xerial-snappy.properties file (under the root path of your library) in Java's property file format.
Here is a list of the available properties:

 * org.xerial.snappy.lib.path   (directory containing a snappyjava's native library)
 * org.xerial.snappy.lib.name   (library file name)
 * org.xerial.snappy.tempdir    (temporary directory to extract a native library bundled in snappy-java)
 * org.xerial.snappy.use.systemlib  (if this value is true, use system installed libsnappyjava.so looking the path specified by java.library.path)

----
Snappy-java is developed by [Taro L. Saito](http://www.xerial.org/leo). Twitter  [@taroleo](http://twitter.com/#!/taroleo)


mod_cluster [![CI Status](https://github.com/modcluster/mod_cluster/workflows/CI/badge.svg)](https://github.com/modcluster/mod_cluster/actions)
===========

Project mod_cluster is an intelligent load balancer. It uses a communication channel to forward requests from a reverse
proxy server to one of a set of application server nodes. Unlike mod_jk and mod_proxy, mod_cluster leverages an
additional connection between the application server nodes and the reverse proxy to transmit server-side load balance
factors and lifecycle events back to the proxy. This additional feedback channel allows mod_cluster to offer a level of
intelligence and granularity not found in other load balancing solutions. There are currently two reverse proxy
implementations: a native [Apache HTTP Server](https://httpd.apache.org/) implementation and a pure Java
[Undertow](http://undertow.io/)-based implementation.

Project mod_cluster boasts the following advantages over other httpd-based load balancers:

* Dynamic configuration of httpd workers
* Server-side load balance factor calculation
* Fine grained web-app lifecycle control
* AJP is optional

[https://www.modcluster.io](https://www.modcluster.io)

Installation Instructions
-------------------------

### JBoss AS 7/WildFly 8 (or newer)

These versions already ship with bundled mod_cluster. It is configured via mod_cluster
subsystem.

### JBoss AS 6

This is the first version of AS that bundled mod_cluster, the configuration is located in
`/server/<profile>/deploy/mod_cluster.sar/META-INF` directory.

### Tomcat 8.5 (or newer)

Distribution archives are provided for each Tomcat version.

1. Obtain the distribution archive corresponding to the intended Tomcat version by either downloading from the project
   website or if building from source located in `dist/target/` directory.
2. Download and unzip or untar the distribution archive and navigate to the extracted directory.
3. Copy the `lib/` directory to the Tomcat installation directory adding jars to its `lib/` directory. If upgrading from
   a different version, it is necessary to remove all jars copied previously.
4. Modify `server.xml` within the `conf` directory and add the mod_cluster listener as documented
   [here](https://docs.modcluster.io/). The minimal listener configuration is as follows:

    ```xml
    <Listener className="org.jboss.modcluster.container.tomcat.ModClusterListener" connectorPort="8080" advertiseInterfaceName="lo0"/>
    ```

Project Structure
-----------------

Project is split up into multiple modules:

```
core (contains the implementation of container-independent core mod_cluster concepts)
container
  spi (SPI classes for container integrations, has no dependencies on a specific web container)
  tomcat-8.5 (Tomcat 8.5 container implementation)
  tomcat-9.0 (Tomcat 9.0 container implementation)
  tomcat-10.1 (Tomcat 10.1 container implementation)
load-spi (SPI classes for load metric computation)
```

Source Code
-----------

Source code for the mod_cluster project is located on GitHub:

[https://github.com/modcluster/mod_cluster](https://github.com/modcluster/mod_cluster)

Building
--------

### Servlet Container Modules

When building from source, first ensure that Maven version 3.2.5 or newer (run `mvn -version`) and JDK 11 or newer
(run `java -version`) are installed. The following command builds modules for all containers:

```
mvn clean install
```

Distribution files for Tomcat will be built in the `dist/target/` directory.

### Code Coverage Report

This project currently supports JaCoCo to generate a code coverage report bound to `verify` goal:

```
mvn clean verify -P coverage
```

The resulting report can be viewed by opening `code-coverage/target/site/jacoco-aggregate/index.html`.

Reporting Issues
----------------

Project mod_cluster uses Red Hat Jira issue tracker under MODCLUSTER project:

[https://issues.redhat.com/browse/MODCLUSTER](https://issues.redhat.com/browse/MODCLUSTER)

License
-------
* [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)