package org.nutz.dao.impl; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.nutz.dao.DaoException; import org.nutz.dao.SqlManager; import org.nutz.dao.SqlNotFoundException; import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; import org.nutz.lang.Streams; import org.nutz.log.Log; import org.nutz.log.Logs; import org.nutz.resource.NutResource; import org.nutz.resource.Scans; /** * 基于行解析的SqlManager * @author wendal(wendal1985@gmail.com) * */ public class FileSqlManager implements SqlManager { private static final Log log = Logs.get(); Map<String, String> sqls = Collections.synchronizedMap(new LinkedHashMap<String, String>()); protected String[] paths; protected boolean allowDuplicate = true; protected String pairBegin = "/*"; protected String pairEnd = "*/"; public FileSqlManager(String... paths) { this.paths = paths; refresh(); } public void refresh() { for (String path : paths) { List<NutResource> list = Scans.me().scan(path, ".(sql|sqlx|sqls)$"); for (NutResource res : list) { int c = count(); log.debugf("load >> %s from root=%s", res.getName(), path); try { add(res.getReader()); } catch (IOException e) { log.warnf("fail to load %s from root=%s", res.getName(), path, e); } log.debugf("load %d sql >> %s from root=%s", (count() - c), res.getName(), path); } } } public void add(Reader r) throws IOException { try { BufferedReader br = null; if (r instanceof BufferedReader) br = (BufferedReader)r; else br = new BufferedReader(r); StringBuilder key = new StringBuilder(); StringBuilder sb = new StringBuilder(); OUT: while (br.ready()) { String line = Streams.nextLineTrim(br); if (line == null) break; if (line.startsWith(pairBegin)) { if (key.length() > 0 && line.contains(pairEnd) && !line.endsWith(pairEnd)) { sb.append(line); continue; } if (key.length() > 0 && sb.length() > 0) { addSql(key.toString(), sb.toString()); } key.setLength(0); sb.setLength(0); if (line.endsWith(pairEnd)) { if (line.length() > 4) key.append(line.substring(2, line.length() - 2).trim()); continue; } else { key.append(line.substring(2).trim()); while (br.ready()) { line = Streams.nextLineTrim(br); if (line == null) break OUT; if (line.endsWith(pairEnd)) { if (line.length() > 2) key.append(line.substring(0, line.length() - 2).trim()); continue OUT; } else { key.append(line); } } } } if (key.length() == 0) { log.infof("skip not key sql line %s", line); continue; } if (sb.length() > 0) sb.append("\n"); sb.append(line); } // 最后一个sql也许是存在的 if (key.length() > 0 && sb.length() > 0) { addSql(key.toString(), sb.toString()); } } finally { Streams.safeClose(r); } } public String get(String key) throws SqlNotFoundException { String sql = sqls.get(key); if (sql == null) throw new SqlNotFoundException(key); return sql; } public Sql create(String key) throws SqlNotFoundException { return Sqls.create(get(key)); } public List<Sql> createCombo(String... keys) { if (keys.length == 0) keys = keys(); List<Sql> list = new ArrayList<Sql>(keys.length); for (String key : keys) { list.add(create(key)); } return list; } public int count() { return sqls.size(); } public String[] keys() { Set<String> keys = sqls.keySet(); return keys.toArray(new String[keys.size()]); } public synchronized void addSql(String key, String value) { log.debugf("key=[%s], sql=[%s]", key, value); if (!isAllowDuplicate() && sqls.containsKey(key)) throw new DaoException("Duplicate sql key=[" +key + "]"); sqls.put(key, value); } public void remove(String key) { sqls.remove(key); } public void setAllowDuplicate(boolean allowDuplicate) { this.allowDuplicate = allowDuplicate; } public boolean isAllowDuplicate() { return allowDuplicate; } /** * 废弃的方法,仅为兼容性保留空方法 */ @Deprecated public String getRegex() { return null; } @Deprecated public FileSqlManager setRegex(String regex) { log.warn("SqlManager regex is Deprecated!! it will be ignore!!"); return this; } }