// ============================================================ // <T>文件列表监视器基类。</T> // <P>1. 监视指定文件列表变动,进行相关处理。</P> // <P>2. 只监视变动,不监视新增和删除文件的操作。</P> // ============================================================ public abstract class FFileListMonitor extends FAbstractMonitor { // 日志输出接口 private static ILogger _logger = RLogger.find(FFileListMonitor.class); // 文件列表 protected FFileInfos _files = new FFileInfos(); // 存储间隔 protected int _storeInterval; // ============================================================ // <T>构造文件列表监视器基类。</T> // ============================================================ public FFileListMonitor() {} // ============================================================ // <T>获得存储间隔。</T> // // @return 存储间隔 // ============================================================ public int storeInterval() { return _storeInterval; } // ============================================================ // <T>设置存储间隔。</T> // // @param storeInterval 存储间隔 // ============================================================ public void setStoreInterval(int storeInterval) { _storeInterval = storeInterval; } // ============================================================ // <T>获得文件信息集合。</T> // // @return 文件信息集合 // ============================================================ public FFileInfos files() { return _files; } // ============================================================ // <T>文档过滤器。</T> // <P>监视器只关心返回TRUE的文件。</P> // // @param info 文件信息 // @return TRUE:成功<br>FALSE:失败 // ============================================================ public boolean onFilter(FFileInfo info) { return (null != info); } // ============================================================ // <T>响应初始化文档。</T> // // @param filename 文件名称 // ============================================================ public void doInitializeFile(FFileInfo info) { if (_logger.debugAble()) { _logger.debug(this, "doInitializeFile", "File initialize (file={1})", info.fileName()); } } // ============================================================ // <T>响应发生变动的文档。</T> // // @param info 文件信息 // ============================================================ public void doFileChange(FFileInfo info) { if (_logger.debugAble()) { _logger.debug(this, "doFileChange", "File change (file={1})", info.fileName()); } } // ============================================================ // <T>响应被保存的文档。</T> // // @param info 文件信息 // ============================================================ public void doFileSave(FFileInfo info) { if (_logger.debugAble()) { _logger.debug(this, "doFileSave", "File save (file={1})", info.fileName()); } } // ============================================================ // <T>响应被移除的文档。</T> // // @param info 文件信息 // ============================================================ public void doFileRemove(FFileInfo info) { if (_logger.debugAble()) { _logger.debug(this, "doFileRemove", "File remove (file={1})", info.fileName()); } } // ============================================================ // <T>执行监视器的逻辑。</T> // // @return 处理结果 // ============================================================ @Override public boolean onExecute() { // 检查文件集合 if (_files.isEmpty()) { return false; } // 检查变更的文件 FFileInfos removes = null; int count = _files.count(); for (int n = 0; n < count; n++) { FFileInfo info = _files.value(n); if (onFilter(info)) { if (info.exists()) { if (info.storeTest(_storeInterval)) { // 响应存储的文件 try { doFileSave(info); } catch (Exception e) { _logger.error(e, "File save event error (file={1})", info.fileName()); } info.stored(); } else if (info.isModified()) { // 响应变更的文件 try { doFileChange(info); } catch (Exception e) { _logger.error(e, "File change event error (file={1})", info.fileName()); } info.refresh(); } } else { // 响应被删除的文件 try { doFileRemove(info); } catch (Exception e) { _logger.error(e, "File remove event error (file={1})", info.fileName()); } if (null == removes) { removes = new FFileInfos(); } removes.push(info); } } } // 移除文件集合 if (null != removes) { for (FFileInfo info : removes.values()) { _files.remove(info.fileName()); } } return true; } // ============================================================ // <T>增加文件信息。</T> // // @param info 文件信息 // ============================================================ public void push(FFileInfo info) { if (null != info) { _files.push(info); } } // ============================================================ // <T>向监视器中增加一个监视文件。</T> // // @param fileName 文件名称 // ============================================================ public void push(String filename) { File file = new File(filename); if (file.isFile()) { _files.push(new FFileInfo(file)); } else { _logger.warn(this, "push", "File is not exists (file={1})", filename); } } // ============================================================ // <T>存储文件。</T> // // @param fileName 文件名称 // ============================================================ public synchronized void store(String fileName) { if (null != fileName) { int count = _files.count(); for (int n = 0; n < count; n++) { if (fileName.equals(_files.value(n).fileName())) { _files.value(n).store(); return; } } if (!RFile.isFile(fileName)) { RFile.saveToFile(fileName, RString.EMPTY); } FFileInfo info = new FFileInfo(fileName); _files.push(info); info.store(); } } // ============================================================ // <T>已经存储文件。</T> // // @param fileName 文件名称 // ============================================================ public synchronized void stored(String fileName) { if (null != fileName) { int count = _files.count(); for (int n = 0; n < count; n++) { if (fileName.equals(_files.value(n).fileName())) { _files.value(n).stored(); break; } } } } // ============================================================ // <T>存储所有变更的文件。</T> // ============================================================ public synchronized void storeAll() { // 检查变更的文件 if (!_files.isEmpty()) { int count = _files.count(); for (int n = 0; n < count; n++) { FFileInfo info = _files.value(n); if (onFilter(info)) { if (info.exists() && info.storeTest(0)) { // 响应存储的文件 try { doFileSave(info); } catch (Exception e) { _logger.error(e, "File save event error (file={1})", info.fileName()); } info.stored(); } } } } } // ============================================================ // <T>从监视器中移除一个监视文件。</T> // // @param info 文件信息 // ============================================================ public boolean remove(FFileInfo info) { if (null != info) { _files.remove(info.fileName()); return true; } return false; } // ============================================================ // <T>从监视器中移除一个监视文件。</T> // // @param fileName 文件名称 // ============================================================ public boolean remove(String fileName) { FFileInfo info = _files.get(fileName); if (null != info) { _files.remove(fileName); return true; } return false; } // ============================================================ // <T>清除监视的文件列表。</T> // ============================================================ public synchronized void clear() { _files.clear(); } }
// ============================================================ // <T>存储信息。</T> // ============================================================ public class SGcStorage { // 日志输出接口 private static final ILogger _logger = RLogger.find(SGcStorage.class); // 分类 protected String _catalog; // 内容类型 protected String _mime; // 类型 protected String _type; // 日期 protected String _date; // 代码 protected String _code; // 当前名称 protected String _name; // 原始名称 protected String _origin; // 扩展名 protected String _extension; // 数据 protected byte[] _data; // 大小 protected int _size; // 网络地址 protected String _uri; // 网络地址 protected String _url; // 图片集合 // protected SGcStorageImages _images = new SGcStorageImages(); // ============================================================ // <T>构造存储信息。</T> // ============================================================ public SGcStorage() { _date = RDateTime.format("YYYYMMDD"); _code = RUuid.makeUniqueIdLower(); _name = RUuid.makeUniqueIdLower(); } // ============================================================ // <T>构造存储信息。</T> // // @param pack 打包字符串 // ============================================================ public SGcStorage(String pack) { unpack(pack); } // ============================================================ // <T>构造存储信息。</T> // // @param catalog 分类 // @param file 文件 // ============================================================ public SGcStorage(String catalog, File file) { // 加载文件 String fileName = file.getAbsolutePath(); loadFile(fileName); // 设置属性 _catalog = catalog; _date = RDateTime.format("YYYYMMDD"); _code = RUuid.makeUniqueIdLower(); _name = RUuid.makeUniqueIdLower(); _origin = file.getName(); _extension = RFile.extension(file); if (!RString.isEmpty(_extension)) { _name += "." + _extension; } } // ============================================================ // <T>构造存储信息。</T> // // @param catalog 分类 // @param file 文件 // ============================================================ public SGcStorage(String catalog, FWebUploadFile file) { // 加载文件 loadFile(file.uploadName()); // 设置属性 _catalog = catalog; _date = RDateTime.format("YYYYMMDD"); _code = RUuid.makeUniqueIdLower(); _name = RUuid.makeUniqueIdLower(); _origin = file.fileName(); _mime = file.contentType(); _extension = RFile.extension(file.fileName()); if (!RString.isEmpty(_extension)) { _name += "." + _extension; } } // ============================================================ // <T>构造存储信息。</T> // // @param catalog 分类 // @param code 代码 // @param file 文件 // ============================================================ public SGcStorage(String catalog, String code, FWebUploadFile file) { // 加载文件 loadFile(file.uploadName()); // 设置属性 _catalog = catalog; _date = RDateTime.format("YYYYMMDD"); _code = code; _name = RUuid.makeUniqueIdLower(); _origin = file.fileName(); _mime = file.contentType(); _extension = RFile.extension(file.fileName()); if (!RString.isEmpty(_extension)) { _name += "." + _extension; } } // ============================================================ // <T>获得分类。</T> // // @return 分类 // ============================================================ public String catalog() { return _catalog; } // ============================================================ // <T>设置分类。</T> // // @param type 分类 // ============================================================ public void setCatalog(String catalog) { _catalog = catalog; } // ============================================================ // <T>获得类型。</T> // // @return 类型 // ============================================================ public String type() { return _type; } // ============================================================ // <T>设置类型。</T> // // @param type 类型 // ============================================================ public void setType(String type) { _type = type; } // ============================================================ // <T>获得日期。</T> // // @return 日期 // ============================================================ public String date() { return _date; } // ============================================================ // <T>设置日期。</T> // // @param date 日期 // ============================================================ public void setDate(String date) { _date = date; } // ============================================================ // <T>获得代码。</T> // // @return 代码 // ============================================================ public String code() { return _code; } // ============================================================ // <T>设置代码。</T> // // @param code 代码 // ============================================================ public void setCode(String code) { _code = code; } // ============================================================ // <T>获得名称。</T> // // @return 名称 // ============================================================ public String name() { return _name; } // ============================================================ // <T>设置名称。</T> // // @param name 名称 // ============================================================ public void setName(String name) { _name = name; } // ============================================================ // <T>获得原始名称。</T> // // @return 原始名称 // ============================================================ public String origin() { return _origin; } // ============================================================ // <T>设置原始名称。</T> // // @param origin 原始名称 // ============================================================ public void setOrigin(String origin) { _origin = origin; } // ============================================================ // <T>获得扩展名。</T> // // @return 扩展名 // ============================================================ public String extension() { return _extension; } // ============================================================ // <T>设置扩展名。</T> // // @param extension 扩展名 // ============================================================ public void setExtension(String extension) { _extension = extension; } // ============================================================ // <T>获得数据。</T> // // @return 数据 // ============================================================ public byte[] data() { return _data; } // ============================================================ // <T>设置数据。</T> // // @param data 数据 // ============================================================ public void setData(byte[] data) { _data = data; } // ============================================================ // <T>获得大小。</T> // // @return 大小 // ============================================================ public int size() { return _size; } // ============================================================ // <T>设置大小。</T> // // @param size 大小 // ============================================================ public void setSize(int size) { _size = size; } // ============================================================ // <T>获得网络地址。</T> // // @return 网络地址 // ============================================================ public String uri() { return _uri; } // ============================================================ // <T>设置网络地址。</T> // // @param url 网络地址 // ============================================================ public void setUri(String uri) { _uri = uri; } // ============================================================ // <T>获得网络地址。</T> // // @return 网络地址 // ============================================================ public String url() { return _url; } // ============================================================ // <T>设置网络地址。</T> // // @param url 网络地址 // ============================================================ public void setUrl(String url) { _url = url; } // //============================================================ // // <T>获得图片集合。</T> // // // // @return 图片集合 // //============================================================ // public SGcStorageImages images(){ // return _images; // } // // //============================================================ // // <T>增加一个图片。</T> // // // // @param width 宽度 // // @param height 高度 // //============================================================ // public void pushImage(int width, // int height){ // pushImage(width, height, 0); // } // // //============================================================ // // <T>增加一个图片。</T> // // // // @param width 宽度 // // @param height 高度 // // @param round 圆角 // //============================================================ // public void pushImage(int width, // int height, // int round){ // SGcStorageImage image = new SGcStorageImage(); // image.setWidth(width); // image.setHeight(height); // image.setRound(round); // //_images.push(image); // } // ============================================================ // <T>设置网络地址。</T> // // @param url 网络地址 // ============================================================ public void loadFile(String fileName) { // 检查文件存在性 if (!RFile.exists(fileName)) { throw new FFatalError("File is not exists. (file_name={1})", fileName); } // 设置名称 if (RString.isEmpty(_name)) { _name = RFile.name(fileName); } // 设置扩展 if (RString.isEmpty(_extension)) { _extension = RFile.extension(fileName); } // 加载文件 try (FByteFile file = new FByteFile(fileName)) { _data = file.toArray(); _size = _data.length; } catch (Exception exception) { _logger.error(this, "loadFile", exception); } } // ============================================================ // <T>打包处理。</T> // // @return 打包字符串 // ============================================================ public String pack() { FAttributes map = new FAttributes(); map.setNvl("catalog", _catalog); map.setNvl("date", _date); map.setNvl("code", _code); map.setNvl("name", _name); map.setNvl("origin", _origin); map.setNvl("mime", _mime); map.setNvl("size", _size); if (map.isEmpty()) { return null; } return map.pack(); } // ============================================================ // <T>解包处理。</T> // // @param pack 打包字符串 // ============================================================ public void unpack(String pack) { if (!RString.isEmpty(pack)) { try { // 解压数据 FAttributes map = new FAttributes(); map.unpack(pack); // 获得内容 _catalog = map.get("catalog", null); _date = map.get("date", null); _code = map.get("code", null); _name = map.get("name", null); _origin = map.get("origin", null); _mime = map.get("mime", null); _size = map.getInt("size"); } catch (Throwable throwable) { _catalog = null; _date = null; _code = null; _name = null; _origin = null; _mime = null; _size = 0; _logger.error(this, "unpack", throwable); } } } }
public class FListConsole extends FXmlConfigConsole<XList> implements IListConsole { private static ILogger _logger = RLogger.find(FListConsole.class); public static final String SQL_CODE_LIST = "code.list"; @ALink protected ICacheConsole _cacheConsole; @AProperty protected long _cacheTimeout; @ALink protected IDatabaseConsole _databaseConsole; @Override public XList build(String name) { XList list = buildItems(get(name)); return list; } @Override public FXmlNodes buildItemNodes(String name) { FXmlNodes nodes = new FXmlNodes(); if (name.startsWith("{") && name.endsWith("}")) { name = name.substring(1, name.length() - 1); // 去数据库去CodeList ISqlConnection cnn = null; try { cnn = _databaseConsole.alloc(); innerBuildCodeList(nodes, name, cnn); } finally { if (null != cnn) { _databaseConsole.free(cnn); } } } else { // 通过列表取数据 innerBuildList(nodes, name); } return nodes; } @Override public FXmlNodes buildItemNodes(TListArgs args) { FXmlNodes nodes = new FXmlNodes(); String name = args.name(); if (name.startsWith("{") && name.endsWith("}")) { name = name.substring(1, name.length() - 1); // 去数据库去CodeList if (null == args.sqlContext()) { ISqlConnection cnn = null; try { cnn = _databaseConsole.alloc(); innerBuildCodeList(nodes, name, cnn); } finally { if (null != cnn) { _databaseConsole.free(cnn); } } } else { innerBuildCodeList(nodes, name, args.sqlContext()); } } else { // 通过列表取数据 innerBuildList(nodes, name); } return nodes; } protected XList buildItems(XList list) { ISqlConnection cnn = null; XList xlist = new XList(); try { int count = list.children().count(); for (int n = 0; n < count; n++) { IXmlObject xobject = list.children().get(n); String type = xobject.innerGet("type"); if (XListItem.TYPE_SQL.equals(type)) { if (null == cnn) { cnn = _databaseConsole.alloc(); } FDataset ds = cnn.fetchDataset(xobject.innerGet("value")); for (FRow row : ds) { XListItem item = new XListItem(); item.innerSet("value", row.value(0)); item.innerSet("label", row.value(1)); xlist.children().push(item); } } else { XListItem item = new XListItem(); item.innerSet("value", xobject.innerGet("value")); item.innerSet("label", xobject.innerGet("label")); xlist.children().push(item); } } } finally { if (null != cnn) { _databaseConsole.free(cnn); } } return xlist; } @Override public FXmlNode buildListConfig(TListArgs args) { String name = args.name(); // 从缓冲管理器中查找列表对象 ICache cache = _cacheConsole.find(IListConsole.class, name); if (null != cache) { return (FXmlNode) cache.instance(); } // 创建节点 FXmlNode config = new FXmlNode("List"); config.set("name", name); if (name.startsWith("{") && name.endsWith("}")) { String code = name.substring(1, name.length() - 1); // 去数据库去CodeList if (null == args.sqlContext()) { ISqlConnection cnn = null; try { cnn = _databaseConsole.alloc(); innerBuildCodeList(config.nodes(), code, cnn); } finally { if (null != cnn) { _databaseConsole.free(cnn); } } } else { innerBuildCodeList(config.nodes(), code, args.sqlContext()); } } else { // 通过列表取数据 innerBuildList(config.nodes(), name); } // 向缓冲管理器中注册列表对象 cache = new FCache(config); cache.setTimeout(_cacheTimeout); _cacheConsole.register(IListConsole.class, name, cache); return config; } @Override protected FObjects<XList> createCollection() { return new FObjects<XList>(XList.class); } protected void innerBuildCodeList(FXmlNodes config, String name, ISqlConnect connect) { // 去数据库去CodeList if (_logger.debugAble()) { _logger.debug(this, "buildItemNodes", "Find item nodes. (codelist={0})", name); } FSqlQuery sql = new FSqlQuery(connect, getClass(), SQL_CODE_LIST); sql.bindString("name", name); FDataset dataset = sql.fetchDataset(); for (FRow row : dataset) { FXmlNode itemNode = config.create(XListItem.NAME); itemNode.set(XListItem.PTY_VALUE, row.get(XListItem.PTY_VALUE)); itemNode.set(XListItem.PTY_LABEL, row.get(XListItem.PTY_LABEL)); } } protected void innerBuildList(FXmlNodes config, String name) { // 通过列表取数据 XList xlist = get(name); if (xlist.hasChild()) { IXmlObjects xitems = xlist.children(); int count = xitems.count(); for (int n = 0; n < count; n++) { XListItem xitem = (XListItem) xitems.get(n); if (null != xitem) { FXmlNode itemNode = config.create(XListItem.NAME); itemNode.set(XListItem.PTY_VALUE, xitem.getValue()); itemNode.set(XListItem.PTY_LABEL, xitem.getLabel()); } } } } }