diff --git a/pom.xml b/pom.xml index 7484b6e..05b7c75 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ org.projectlombok lombok true + provided 1.18.30 @@ -71,6 +72,20 @@ maven-compiler-plugin 3.11.0 + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + org.apache.maven.plugins maven-assembly-plugin diff --git a/src/main/java/org/aohe/core/sane/SaneOperational.java b/src/main/java/org/aohe/core/sane/SaneOperational.java index 6028f7b..1b66a55 100644 --- a/src/main/java/org/aohe/core/sane/SaneOperational.java +++ b/src/main/java/org/aohe/core/sane/SaneOperational.java @@ -2,6 +2,7 @@ package org.aohe.core.sane; import au.com.southsky.jfreesane.SaneDevice; import au.com.southsky.jfreesane.SaneException; +import au.com.southsky.jfreesane.SaneOption; import cn.hutool.core.codec.Base64; import com.alibaba.fastjson2.JSONObject; import lombok.extern.slf4j.Slf4j; @@ -39,7 +40,7 @@ public class SaneOperational { r = setScanner(param.getString("scannerId")); }else if ("001003".equals(function)){ //获取扫描仪操作符列表 - // r = getDeviceOperations(); + r = getOptions(param.getString("name")); }else if ("001004".equals(function)){ //r = setDeviceOperations(); }else if ("001007".equals(function)){ @@ -54,7 +55,6 @@ public class SaneOperational { //r = startScan(param.getString("scannerId"),true); }else if ("001016".equals(function)){ //r = startScan(param.getString("scannerId"),true); - SaneSessionUtils.printUsedIp(); r = R.ok(); } }catch (Exception e){ @@ -92,12 +92,12 @@ public class SaneOperational { if(saneDrivers == null){ saneDrivers = scannerId; } - SaneSessionUtils.setSaneDevice(scannerId); return R.ok(); } catch (SaneException | IOException e) { - throw new RuntimeException(e); + log.error("打开扫描仪失败" , e); } + return R.fail("打开扫描仪失败"); } /** @@ -125,7 +125,16 @@ public class SaneOperational { return R.ok(list); } catch (IOException e) { - throw new RuntimeException(e); + log.error("扫描失败 ", e); } + return R.fail("扫描失败"); + } + + public static R getOptions(String name){ + List options = SaneSessionUtils.getOptions(name); + if(options != null && !options.isEmpty()){ + return R.ok(options); + } + return R.fail("调用失败"); } } diff --git a/src/main/java/org/aohe/core/sane/mode/ScanMode.java b/src/main/java/org/aohe/core/sane/mode/ScanMode.java new file mode 100644 index 0000000..7ba150f --- /dev/null +++ b/src/main/java/org/aohe/core/sane/mode/ScanMode.java @@ -0,0 +1,7 @@ +package org.aohe.core.sane.mode; + +public enum ScanMode { + Lineart, + Gray, + Color +} \ No newline at end of file diff --git a/src/main/java/org/aohe/core/sane/utils/SaneSessionUtils.java b/src/main/java/org/aohe/core/sane/utils/SaneSessionUtils.java index a096061..652d3f0 100644 --- a/src/main/java/org/aohe/core/sane/utils/SaneSessionUtils.java +++ b/src/main/java/org/aohe/core/sane/utils/SaneSessionUtils.java @@ -2,27 +2,30 @@ package org.aohe.core.sane.utils; import au.com.southsky.jfreesane.SaneDevice; import au.com.southsky.jfreesane.SaneException; +import au.com.southsky.jfreesane.SaneOption; import au.com.southsky.jfreesane.SaneSession; import cn.hutool.core.io.FileUtil; -import cn.hutool.core.net.Ipv4Util; -import cn.hutool.core.net.NetUtil; -import cn.hutool.core.util.ByteUtil; -import cn.hutool.core.util.RuntimeUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; import lombok.extern.slf4j.Slf4j; -import org.aohe.core.utils.CommandUtils; -import org.aohe.core.utils.SystemUtils; +import org.aohe.core.result.R; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; + +import java.util.LinkedHashMap; import java.util.List; -import java.util.concurrent.ExecutorService; +import java.util.Map; + +import au.com.southsky.jfreesane.OptionValueType; +import org.aohe.core.sane.mode.ScanMode; @Slf4j public class SaneSessionUtils { @@ -35,8 +38,6 @@ public class SaneSessionUtils { private static final RemoteConfig remoteConfig = RemoteConfig.getInstance(); - private static List beUsedIp = new ArrayList<>(64); - /** * 获取一个SaneSession实例,用于与SANE设备进行通信 * @return SaneSession实例 @@ -118,6 +119,9 @@ public class SaneSessionUtils { */ public static SaneDevice getDevice(String name) { try { + if(StrUtil.isBlank(name)){ + return saneDevice; + } return setSaneDevice(name); } catch (IOException | SaneException e) { throw new RuntimeException(e); @@ -149,7 +153,185 @@ public class SaneSessionUtils { } } } - + + /** + * 获取扫描仪参数 + * @return list + * @throws IOException io异常 + * @throws SaneException 扫描异常 + */ + public static List getOptions(String name){ + SaneDevice saneDevice = getDevice(name); + if (saneDevice == null) { + return null; + } + try { + if (!saneDevice.isOpen()) { + saneDevice.open(); + } + return saneDevice.listOptions(); + } catch (IOException | SaneException e ) { + log.error("系统错误 ", e); + return null; + } + + } + +// /** +// * BW - 0 +// * COLOR - 2 +// * GRAYSCALE - 1 +// * true ->auto +// * @param params +// */ +// /** +// * 设置参数 +// * @param params 参数 Dpi ->double 0-bw 2-color 1-gray true-auto +// * @throws SaneException 系统错误 +// */ +// public static void setOption(JSONObject params) throws SaneException, IOException { +// if(saneDevice == null){ +// throw new SaneException("please first set device"); +// } +// if(params == null){ +// return; +// } +// Double key = params.getDouble("dpi"); +// if(key != null){ +// SaneOption dpi = saneDevice.getOption("Dpi"); +// dpi.setIntegerValue(key.intValue()); +// } +// +// Integer mode = params.getInteger("mode"); +// if(mode != null){ +// saneDevice.getOption("model"); +// switch (mode){ +// case 0: +// source.setColor(Source.ColorMode.BW); +// break; +// case 1: +// source.setColor(Source.ColorMode.GRAYSCALE); +// break; +// case 2: +// default: +// source.setColor(Source.ColorMode.COLOR); +// } +// } +// +// Boolean paperMode = params.getBoolean("paperMode"); +// if(paperMode != null){ +// source.setAutoDocumentFeeder(paperMode); +// } +// +// Boolean systemUI = params.getBoolean("systemUI"); +// if(systemUI != null){ +// source.setSystemUI(systemUI); +// } +// } + + /** + * 设置扫描仪 + * @param deviceName + * @param options + * @return + * @throws IOException + * @throws SaneException + */ + private R doSetOptions(String deviceName, LinkedHashMap options) throws IOException, SaneException { + SaneDevice saneDevice = getDevice(deviceName); + + if (saneDevice == null) { + return null; + } + if (!saneDevice.isOpen()) { + saneDevice.open(); + } + for (Map.Entry entry : options.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + SaneOption option = saneDevice.getOption(key); + if (ObjectUtil.isEmpty(option)) { + String errorMessage = String.format("option %s is not null,请检查该属性值是否含有使用条件.", key); + return R.fail(errorMessage); + } + OptionValueType optionType = option.getType(); + if (!option.isActive()) { + String errorMessage2 = String.format("option %s is not active,请检查该属性值是否含有使用条件.%n option %s description:%s", option.getName(), option.getName(), option.getDescription()); + return R.fail(errorMessage2); + } + switch (optionType) { + case BOOLEAN: + boolean val = Boolean.parseBoolean(String.valueOf(value)); + option.setBooleanValue(val); + break; + case INT: + try { + int intVal = Integer.parseInt(String.valueOf(value)); + int max = option.getRangeConstraints().getMaximumInteger(); + int min = option.getRangeConstraints().getMinimumInteger(); + int quantum = option.getRangeConstraints().getQuantumInteger(); + if (intVal % quantum != 0 || intVal > max || intVal < min) { + String errorMessage3 = String.format("无效的%s值%s,有效范围为:[%s-%s],Quantum:%s", key, value, Integer.valueOf(min), Integer.valueOf(max), Integer.valueOf(quantum)); + log.error(errorMessage3); + return R.fail(errorMessage3); + } + option.setIntegerValue(intVal); + break; + } catch (Exception nfe) { + String errorMessage4 = String.format("错误的Int类型值%s", value); + log.error(errorMessage4, nfe); + return R.fail(errorMessage4); + } + case FIXED: + try { + double doubleVal = Double.parseDouble(String.valueOf(value)); + double max2 = BigDecimal.valueOf(option.getRangeConstraints().getMaximumFixed()).setScale(2, RoundingMode.HALF_UP).doubleValue(); + double min2 = BigDecimal.valueOf(option.getRangeConstraints().getMinimumFixed()).setScale(2, RoundingMode.HALF_UP).doubleValue(); + double quantum2 = BigDecimal.valueOf(option.getRangeConstraints().getQuantumFixed()).setScale(2, RoundingMode.HALF_UP).doubleValue(); + if ((doubleVal / quantum2) % 1.0d != 0.0d || doubleVal > max2 || doubleVal < min2) { + String errorMessage5 = String.format("无效的%s值%s,有效范围为:[%s-%s],Quantum:%s", key, value, Double.valueOf(min2), Double.valueOf(max2), Double.valueOf(quantum2)); + log.warn(errorMessage5); + return R.fail(errorMessage5); + } + option.setFixedValue(doubleVal); + break; + } catch (Exception nfe2) { + String errorMessage6 = String.format("错误的Double类型值%s", value); + log.error(errorMessage6, nfe2); + return R.fail(errorMessage6); + } + case STRING: + try { + String stringVal = value.toString(); + List effectiveValues = option.getStringConstraints(); + if (effectiveValues != null) { + if (!effectiveValues.contains(stringVal)) { + String errorMessage7 = String.format("无效的%s值%s,有效范围为:[%s]", key, value, String.join(",", effectiveValues)); + log.warn(errorMessage7); + return R.fail(errorMessage7); + } + option.setStringValue(stringVal); + if (option.getName().equals(getModeString())) { + //SaneSessionUtil.scanMode = (ScanMode) Enum.valueOf(ScanMode.class, stringVal); + } + } + break; + } catch (Exception nfe3) { + String errorMessage8 = String.format("错误的String类型值%s", value); + log.error(errorMessage8, nfe3); + return R.fail(errorMessage8); + } + } + } + return R.ok(); + } + + public static String getModeString() { + return "mode"; + } + + + /** * 释放资源 */ @@ -181,48 +363,7 @@ public class SaneSessionUtils { } - /** - * 测试可用ip - * @param ips ip - */ - public static void beUsed(List ips){ - try (ExecutorService executorService = SystemUtils.newFixedThreadPool(2);){ - for(String ip : ips){ - log.info("ip:{} , 开始检测", ip); - executorService.submit(() -> SaneSessionUtils.beUsed(ip)); - } - }catch (Exception e){ - log.info("查找出错 "); - } - } - /** - * 测试可用ip - * @param ip ip - */ - public static void beUsed(String ip){ - log.info("ip:{} , 可用性测试开始", ip); - if(!NetUtil.ping(ip)){ - log.info("ip:{} , ping 测试不通过", ip); - return; - } - try (SaneSession session = SaneSession.withRemoteSane(InetAddress.getByName(ip))){ - if(session == null){ - - return; - } - log.info("ip:{} , session 打开成功", ip); - //添加到可用列表 - beUsedIp.add(ip); - } catch (IOException e) { - log.info("ip:{} , session 打开失败", ip); - throw new RuntimeException(e); - } - } - - public static void printUsedIp(){ - log.info("可用ip {} ", String.join("|", beUsedIp)); - } } diff --git a/src/main/java/org/aohe/core/utils/SystemUtils.java b/src/main/java/org/aohe/core/utils/SystemUtils.java index 3f00aa6..a24a5c9 100644 --- a/src/main/java/org/aohe/core/utils/SystemUtils.java +++ b/src/main/java/org/aohe/core/utils/SystemUtils.java @@ -81,10 +81,10 @@ public class SystemUtils { } /** - * 获取第一个内网网卡地址 + * 获取第一个内网网卡地址和掩码 * @return 地址 */ - public static String getInnerFirstEth(){ + public static String getInnerFirstEthMask(){ Enumeration netInterfaces; try { // 拿到所有网卡 @@ -121,21 +121,4 @@ public class SystemUtils { return "127.0.0.1/24"; } - public static void main(String[] args) throws InterruptedException { - String ip = getInnerFirstEth(); - List list = Ipv4Util.list(ip, false); - SaneSessionUtils.beUsed(list); - - while (true){ - Thread.sleep(10000); - SaneSessionUtils.printUsedIp(); - } - } - - public static ExecutorService newFixedThreadPool(int nThreads) { - return new ThreadPoolExecutor(nThreads, nThreads, - 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue<>()); - } - } \ No newline at end of file