Browse Source

Merge pull request #5808 in CORE/base-third from release/11.0 to bugfix/11.0

* commit '2adee25ebf01ebf8d0f99887a9310a63008e3126':
  REPORT-71241 大数据集导出变慢
  REPORT-71241 大数据集导出变慢
  REPORT-71241 大数据集导出变慢
  REPORT-71021 恢复创建线程启停机制
bugfix/KERNEL-11409-jackson
superman 3 years ago
parent
commit
f905edbaa3
  1. 4
      fine-druid/readme.MD
  2. 287
      fine-druid/src/main/java/com/fr/third/alibaba/druid/pool/DruidDataSource.java
  3. 28
      fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/hssf/usermodel/HSSFCell.java
  4. 8
      fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/ss/usermodel/Cell.java
  5. 5
      fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/xssf/streaming/SXSSFCell.java
  6. 192
      fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/xssf/streaming/SheetDataWriter.java
  7. 68
      fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/xssf/usermodel/XSSFCell.java

4
fine-druid/readme.MD

@ -1,9 +1,10 @@
# Alibaba Druid # Alibaba Druid
- FineReport更新时间 `2022-04-27` - FineReport更新时间 `2022-04-27`
- Druid版本 1.2.9 - Druid版本 1.2.9
- [github地址](https://github.com/alibaba/druid) - [github地址](https://github.com/alibaba/druid)
## 变动列表 ## 变动列表
> 由于需要适配数据源的一些特性和默认配置,对Druid有部分修改,后续更新都要保留下列修改 > 由于需要适配数据源的一些特性和默认配置,对Druid有部分修改,后续更新都要保留下列修改
@ -14,3 +15,4 @@
| 1.2.9 | 2022-05-05 | MysqlUtils.getLastPacketReceivedTimeMs根据类加载器区分连接实现等,不在使用全局变量 | | 1.2.9 | 2022-05-05 | MysqlUtils.getLastPacketReceivedTimeMs根据类加载器区分连接实现等,不在使用全局变量 |
| 1.2.9 | 2022-05-05 | com.fr.third.alibaba.druid.util.Utils.loadClass改为优先从线程类加载器加载类 | | 1.2.9 | 2022-05-05 | com.fr.third.alibaba.druid.util.Utils.loadClass改为优先从线程类加载器加载类 |
| 1.2.9 | 2022-05-05 | 恢复com.fr.third.alibaba.druid.pool.DruidDataSourceFactory对hibernate配置属性的支持 | | 1.2.9 | 2022-05-05 | 恢复com.fr.third.alibaba.druid.pool.DruidDataSourceFactory对hibernate配置属性的支持 |
| 1.2.9 | 2022-05-10 | 恢复DruidDataSource中的创建线程启停机制 |

287
fine-druid/src/main/java/com/fr/third/alibaba/druid/pool/DruidDataSource.java

@ -134,6 +134,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
private volatile Future<?> createSchedulerFuture; private volatile Future<?> createSchedulerFuture;
private CreateConnectionThread createConnectionThread; private CreateConnectionThread createConnectionThread;
private PeriodDetectionThread periodDetectionThread;
private DestroyConnectionThread destroyConnectionThread; private DestroyConnectionThread destroyConnectionThread;
private LogStatsThread logStatsThread; private LogStatsThread logStatsThread;
private int createTaskCount; private int createTaskCount;
@ -141,7 +142,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
private volatile long createTaskIdSeed = 1L; private volatile long createTaskIdSeed = 1L;
private long[] createTasks; private long[] createTasks;
private final CountDownLatch initedLatch = new CountDownLatch(2); private CountDownLatch initedLatch = new CountDownLatch(2);
private volatile boolean enable = true; private volatile boolean enable = true;
@ -161,6 +162,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
public static ThreadLocal<Long> waitNanosLocal = new ThreadLocal<Long>(); public static ThreadLocal<Long> waitNanosLocal = new ThreadLocal<Long>();
private boolean logDifferentThread = true; private boolean logDifferentThread = true;
private volatile boolean keepAlive = false; private volatile boolean keepAlive = false;
private SQLException initException = null;
private boolean asyncInit = false; private boolean asyncInit = false;
protected boolean killWhenSocketReadTimeout = false; protected boolean killWhenSocketReadTimeout = false;
protected boolean checkExecuteTime = false; protected boolean checkExecuteTime = false;
@ -178,11 +180,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
protected static final AtomicLongFieldUpdater<DruidDataSource> createTaskIdSeedUpdater protected static final AtomicLongFieldUpdater<DruidDataSource> createTaskIdSeedUpdater
= AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "createTaskIdSeed"); = AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "createTaskIdSeed");
public DruidDataSource(){ public DruidDataSource() {
this(false); this(false);
} }
public DruidDataSource(boolean fairLock){ public DruidDataSource(boolean fairLock) {
super(fairLock); super(fairLock);
configFromPropety(System.getProperties()); configFromPropety(System.getProperties());
@ -526,6 +528,45 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
} }
private synchronized void doSomethingBeforeCreationThreadBreak() {
String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this) + this.getUrl();
createConnectionThread = new CreateConnectionThread(threadName);
createConnectionThread.setStarted(false);
String destroyName = "Druid-ConnectionPool-Destroy-" + System.identityHashCode(this) + this.getUrl();
if (destroyConnectionThread != null) {
if (!destroyConnectionThread.isInterrupted()) {
destroyConnectionThread.interrupt();
}
}
destroyConnectionThread = new DestroyConnectionThread(destroyName);
destroyConnectionThread.setStarted(false);
initedLatch = new CountDownLatch(2);
}
private void checkThread() throws SQLException {
if (createConnectionThread == null) {
throw new IllegalStateException("createConnectionThread not start!");
}
if (destroyConnectionThread == null) {
throw new IllegalStateException("destroyConnectionThread not start!");
}
if (!createConnectionThread.isStarted() && !destroyConnectionThread.isStarted()) {
synchronized (this) {//线程安全问题,加个双检锁
if (!createConnectionThread.isStarted() && !destroyConnectionThread.isStarted()) {
createConnectionThread.setStarted(true);
createConnectionThread.start();
destroyConnectionThread.setStarted(true);
destroyConnectionThread.start();
try {
initedLatch.await();
} catch (InterruptedException e) {
throw new SQLException(e.getMessage(), e);
}
}
}
}
}
public boolean isKillWhenSocketReadTimeout() { public boolean isKillWhenSocketReadTimeout() {
return killWhenSocketReadTimeout; return killWhenSocketReadTimeout;
} }
@ -798,6 +839,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
public void init() throws SQLException { public void init() throws SQLException {
if (initException != null) {
LOG.error("{dataSource-" + this.getID() + "} init error", initException);
throw initException;
}
if (inited) { if (inited) {
return; return;
} }
@ -944,6 +990,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
createAndLogThread(); createAndLogThread();
createAndStartCreatorThread(); createAndStartCreatorThread();
createAndStartDestroyThread(); createAndStartDestroyThread();
createAndStartDetectThread();
initedLatch.await(); initedLatch.await();
init = true; init = true;
@ -968,16 +1015,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} catch (SQLException e) { } catch (SQLException e) {
LOG.error("{dataSource-" + this.getID() + "} init error", e); LOG.error("{dataSource-" + this.getID() + "} init error", e);
initException = e;
throw e; throw e;
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new SQLException(e.getMessage(), e); throw new SQLException(e.getMessage(), e);
} catch (RuntimeException e){ } catch (Throwable e) {
LOG.error("{dataSource-" + this.getID() + "} init error", e); initException = new SQLException(e.getMessage());
throw e;
} catch (Error e){
LOG.error("{dataSource-" + this.getID() + "} init error", e);
throw e; throw e;
} finally { } finally {
inited = true; inited = true;
lock.unlock(); lock.unlock();
@ -1075,7 +1119,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
period = 1000; period = 1000;
} }
destroySchedulerFuture = destroyScheduler.scheduleAtFixedRate(destroyTask, period, period, destroySchedulerFuture = destroyScheduler.scheduleAtFixedRate(destroyTask, period, period,
TimeUnit.MILLISECONDS); TimeUnit.MILLISECONDS);
initedLatch.countDown(); initedLatch.countDown();
return; return;
} }
@ -1087,7 +1131,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
protected void createAndStartCreatorThread() { protected void createAndStartCreatorThread() {
if (createScheduler == null) { if (createScheduler == null) {
String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this); String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this) + this.getUrl();
createConnectionThread = new CreateConnectionThread(threadName); createConnectionThread = new CreateConnectionThread(threadName);
createConnectionThread.start(); createConnectionThread.start();
return; return;
@ -1096,9 +1140,18 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
initedLatch.countDown(); initedLatch.countDown();
} }
private void createAndStartDetectThread() {
if (createScheduler == null) {
String threadName = "Druid-ConnectionPool-Detection-" + System.identityHashCode(this) + this.getUrl();
periodDetectionThread = new PeriodDetectionThread(threadName);
periodDetectionThread.start();
}
}
/** /**
* load filters from SPI ServiceLoader * load filters from SPI ServiceLoader
* *
* @see ServiceLoader * @see ServiceLoader
*/ */
private void initFromSPIServiceLoader() { private void initFromSPIServiceLoader() {
@ -1149,7 +1202,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
/** /**
* 会去重复 * 会去重复
* *
* @param filter * @param filter
*/ */
private void addFilter(Filter filter) { private void addFilter(Filter filter) {
@ -1181,21 +1234,21 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
return; return;
} }
String errorMessage = ""; String infoMessage = "";
if (testOnBorrow) { if (isTestOnBorrow()) {
errorMessage += "testOnBorrow is true, "; infoMessage += "testOnBorrow is true, ";
} }
if (testOnReturn) { if (isTestOnReturn()) {
errorMessage += "testOnReturn is true, "; infoMessage += "testOnReturn is true, ";
} }
if (testWhileIdle) { if (isTestWhileIdle()) {
errorMessage += "testWhileIdle is true, "; infoMessage += "testWhileIdle is true, ";
} }
LOG.error(errorMessage + "validationQuery not set"); LOG.info(infoMessage + "validationQuery not set");
} }
protected void resolveDriver() throws SQLException { protected void resolveDriver() throws SQLException {
@ -1233,7 +1286,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if (driver.getMajorVersion() < 10) { if (driver.getMajorVersion() < 10) {
throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "." throw new SQLException("not support oracle driver " + driver.getMajorVersion() + "."
+ driver.getMinorVersion()); + driver.getMinorVersion());
} }
if (driver.getMajorVersion() == 10 && isUseOracleImplicitCache()) { if (driver.getMajorVersion() == 10 && isUseOracleImplicitCache()) {
@ -1277,7 +1330,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if (query instanceof SQLSelectQueryBlock) { if (query instanceof SQLSelectQueryBlock) {
if (((SQLSelectQueryBlock) query).getFrom() == null) { if (((SQLSelectQueryBlock) query).getFrom() == null) {
LOG.error("invalid oracle validationQuery. " + validationQuery + ", may should be : " + validationQuery LOG.error("invalid oracle validationQuery. " + validationQuery + ", may should be : " + validationQuery
+ " FROM DUAL"); + " FROM DUAL");
} }
} }
} }
@ -1306,7 +1359,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if (query instanceof SQLSelectQueryBlock) { if (query instanceof SQLSelectQueryBlock) {
if (((SQLSelectQueryBlock) query).getFrom() == null) { if (((SQLSelectQueryBlock) query).getFrom() == null) {
LOG.error("invalid db2 validationQuery. " + validationQuery + ", may should be : " + validationQuery LOG.error("invalid db2 validationQuery. " + validationQuery + ", may should be : " + validationQuery
+ " FROM SYSDUMMY"); + " FROM SYSDUMMY");
} }
} }
} }
@ -1325,8 +1378,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
this.validConnectionChecker = new OracleValidConnectionChecker(); this.validConnectionChecker = new OracleValidConnectionChecker();
} else if (realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER) } else if (realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER)
|| realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_SQLJDBC4) || realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_SQLJDBC4)
|| realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_JTDS)) { || realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_JTDS)) {
this.validConnectionChecker = new MSSQLValidConnectionChecker(); this.validConnectionChecker = new MSSQLValidConnectionChecker();
} else if (realDriverClassName.equals(JdbcConstants.POSTGRESQL_DRIVER) } else if (realDriverClassName.equals(JdbcConstants.POSTGRESQL_DRIVER)
@ -1351,7 +1404,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
for (Class<?> driverClass = driver.getClass();;) { for (Class<?> driverClass = driver.getClass(); ; ) {
String realDriverClassName = driverClass.getName(); String realDriverClassName = driverClass.getName();
if (realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER) // if (realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER) //
|| realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER_6)) { || realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER_6)) {
@ -1402,6 +1455,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException { public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
init(); init();
checkThread();
if (filters.size() > 0) { if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(this); FilterChainImpl filterChain = new FilterChainImpl(this);
return filterChain.dataSource_connect(this, maxWaitMillis); return filterChain.dataSource_connect(this, maxWaitMillis);
@ -1422,7 +1476,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException { public DruidPooledConnection getConnectionDirect(long maxWaitMillis) throws SQLException {
int notFullTimeoutRetryCnt = 0; int notFullTimeoutRetryCnt = 0;
for (;;) { for (; ; ) {
// handle notFullTimeoutRetry // handle notFullTimeoutRetry
DruidPooledConnection poolableConnection; DruidPooledConnection poolableConnection;
try { try {
@ -1456,10 +1510,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if (testWhileIdle) { if (testWhileIdle) {
final DruidConnectionHolder holder = poolableConnection.holder; final DruidConnectionHolder holder = poolableConnection.holder;
long currentTimeMillis = System.currentTimeMillis(); long currentTimeMillis = System.currentTimeMillis();
long lastActiveTimeMillis = holder.lastActiveTimeMillis; long lastActiveTimeMillis = holder.lastActiveTimeMillis;
long lastExecTimeMillis = holder.lastExecTimeMillis; long lastExecTimeMillis = holder.lastExecTimeMillis;
long lastKeepTimeMillis = holder.lastKeepTimeMillis; long lastKeepTimeMillis = holder.lastKeepTimeMillis;
if (checkExecuteTime if (checkExecuteTime
&& lastExecTimeMillis != lastActiveTimeMillis) { && lastExecTimeMillis != lastActiveTimeMillis) {
@ -1470,7 +1524,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
lastActiveTimeMillis = lastKeepTimeMillis; lastActiveTimeMillis = lastKeepTimeMillis;
} }
long idleMillis = currentTimeMillis - lastActiveTimeMillis; long idleMillis = currentTimeMillis - lastActiveTimeMillis;
long timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis; long timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;
@ -1480,7 +1534,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if (idleMillis >= timeBetweenEvictionRunsMillis if (idleMillis >= timeBetweenEvictionRunsMillis
|| idleMillis < 0 // unexcepted branch || idleMillis < 0 // unexcepted branch
) { ) {
boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn); boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
if (!validate) { if (!validate) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
@ -1488,7 +1542,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
discardConnection(poolableConnection.holder); discardConnection(poolableConnection.holder);
continue; continue;
} }
} }
} }
@ -1518,7 +1572,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
/** /**
* 抛弃连接不进行回收而是抛弃 * 抛弃连接不进行回收而是抛弃
* *
* @param realConnection * @param realConnection
* @deprecated * @deprecated
*/ */
@ -1591,7 +1645,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
DruidConnectionHolder holder; DruidConnectionHolder holder;
for (boolean createDirect = false;;) { for (boolean createDirect = false; ; ) {
if (createDirect) { if (createDirect) {
createStartNanosUpdater.set(this, System.nanoTime()); createStartNanosUpdater.set(this, System.nanoTime());
if (creatingCountUpdater.compareAndSet(this, 0, 1)) { if (creatingCountUpdater.compareAndSet(this, 0, 1)) {
@ -1740,10 +1794,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
StringBuilder buf = new StringBuilder(128); StringBuilder buf = new StringBuilder(128);
buf.append("wait millis ")// buf.append("wait millis ")//
.append(waitNanos / (1000 * 1000))// .append(waitNanos / (1000 * 1000))//
.append(", active ").append(activeCount)// .append(", active ").append(activeCount)//
.append(", maxActive ").append(maxActive)// .append(", maxActive ").append(maxActive)//
.append(", creating ").append(creatingCount)// .append(", creating ").append(creatingCount)//
; ;
if (creatingCount > 0 && createStartNanos > 0) { if (creatingCount > 0 && createStartNanos > 0) {
long createElapseMillis = (System.nanoTime() - createStartNanos) / (1000 * 1000); long createElapseMillis = (System.nanoTime() - createStartNanos) / (1000 * 1000);
@ -1756,17 +1810,21 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
buf.append(", createErrorCount ").append(createErrorCount); buf.append(", createErrorCount ").append(createErrorCount);
} }
List<JdbcSqlStatValue> sqlList = this.getDataSourceStat().getRuningSqlList(); JdbcDataSourceStat sourceStat = this.getDataSourceStat();
for (int i = 0; i < sqlList.size(); ++i) { if (sourceStat != null) {
if (i != 0) { List<JdbcSqlStatValue> sqlList = sourceStat.getRuningSqlList();
buf.append('\n'); for (int i = 0; i < sqlList.size(); ++i) {
} else { if (i != 0) {
buf.append(", "); buf.append('\n');
} else {
buf.append(", ");
}
JdbcSqlStatValue sql = sqlList.get(i);
buf.append("runningSqlCount ");
buf.append(sql.getRunningCount());
buf.append(" : ");
buf.append(sql.getSql());
} }
JdbcSqlStatValue sql = sqlList.get(i);
buf.append("runningSqlCount ").append(sql.getRunningCount());
buf.append(" : ");
buf.append(sql.getSql());
} }
String errorMessage = buf.toString(); String errorMessage = buf.toString();
@ -1858,13 +1916,12 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
lock.unlock(); lock.unlock();
} }
if(onFatalError && holder != null && holder.getDataSource() != null) { if (onFatalError && holder != null && holder.getDataSource() != null) {
ReentrantLock dataSourceLock = holder.getDataSource().lock; ReentrantLock dataSourceLock = holder.getDataSource().lock;
dataSourceLock.lock(); dataSourceLock.lock();
try { try {
emptySignal(); emptySignal();
} } finally {
finally {
dataSourceLock.unlock(); dataSourceLock.unlock();
} }
} }
@ -1901,8 +1958,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
if (logDifferentThread // if (logDifferentThread //
&& (!isAsyncCloseConnectionEnable()) // && (!isAsyncCloseConnectionEnable()) //
&& pooledConnection.ownerThread != Thread.currentThread()// && pooledConnection.ownerThread != Thread.currentThread()//
) { ) {
LOG.warn("get/close not same thread"); LOG.warn("get/close not same thread");
} }
@ -2097,6 +2154,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
destroyConnectionThread.interrupt(); destroyConnectionThread.interrupt();
} }
if (periodDetectionThread != null) {
periodDetectionThread.interrupt();
}
if (createSchedulerFuture != null) { if (createSchedulerFuture != null) {
createSchedulerFuture.cancel(true); createSchedulerFuture.cancel(true);
} }
@ -2154,7 +2215,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
@Override @Override
public Object run() { public Object run() {
ObjectName objectName = DruidDataSourceStatManager.addDataSource(DruidDataSource.this, ObjectName objectName = DruidDataSourceStatManager.addDataSource(DruidDataSource.this,
DruidDataSource.this.name); DruidDataSource.this.name);
DruidDataSource.this.setObjectName(objectName); DruidDataSource.this.setObjectName(objectName);
DruidDataSource.this.mbeanRegistered = true; DruidDataSource.this.mbeanRegistered = true;
@ -2248,7 +2309,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
private DruidConnectionHolder pollLast(long nanos) throws InterruptedException, SQLException { private DruidConnectionHolder pollLast(long nanos) throws InterruptedException, SQLException {
long estimate = nanos; long estimate = nanos;
for (;;) { for (; ; ) {
if (poolingCount == 0) { if (poolingCount == 0) {
emptySignal(); // send signal to CreateThread create connection emptySignal(); // send signal to CreateThread create connection
@ -2269,8 +2330,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
try { try {
long startEstimate = estimate; long startEstimate = estimate;
estimate = notEmpty.awaitNanos(estimate); // signal by estimate = notEmpty.awaitNanos(estimate); // signal by
// recycle or // recycle or
// creator // creator
notEmptyWaitCount++; notEmptyWaitCount++;
notEmptyWaitNanos += (startEstimate - estimate); notEmptyWaitNanos += (startEstimate - estimate);
@ -2494,7 +2555,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
value.setCommitCount(commitCountUpdater.getAndSet(this, 0)); value.setCommitCount(commitCountUpdater.getAndSet(this, 0));
value.setRollbackCount(rollbackCountUpdater.getAndSet(this, 0)); value.setRollbackCount(rollbackCountUpdater.getAndSet(this, 0));
value.setPstmtCacheHitCount(cachedPreparedStatementHitCountUpdater.getAndSet(this,0)); value.setPstmtCacheHitCount(cachedPreparedStatementHitCountUpdater.getAndSet(this, 0));
value.setPstmtCacheMissCount(cachedPreparedStatementMissCountUpdater.getAndSet(this, 0)); value.setPstmtCacheMissCount(cachedPreparedStatementMissCountUpdater.getAndSet(this, 0));
value.setStartTransactionCount(startTransactionCountUpdater.getAndSet(this, 0)); value.setStartTransactionCount(startTransactionCountUpdater.getAndSet(this, 0));
@ -2572,7 +2633,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
clearCreateTask(createTaskId); clearCreateTask(createTaskId);
if (poolingCount + createTaskCount < notEmptyWaitThreadCount // if (poolingCount + createTaskCount < notEmptyWaitThreadCount //
&& activeCount + poolingCount + createTaskCount < maxActive) { && activeCount + poolingCount + createTaskCount < maxActive) {
emptySignal(); emptySignal();
} }
} }
@ -2584,7 +2645,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
public class CreateConnectionTask implements Runnable { public class CreateConnectionTask implements Runnable {
private int errorCount = 0; private int errorCount = 0;
private boolean initTask = false; private boolean initTask = false;
private final long taskId; private final long taskId;
@ -2603,7 +2664,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
private void runInternal() { private void runInternal() {
for (;;) { for (; ; ) {
// addLast // addLast
lock.lock(); lock.lock();
@ -2769,8 +2830,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
public class CreateConnectionThread extends Thread { public class CreateConnectionThread extends Thread {
private volatile boolean started = true;
public CreateConnectionThread(String name){ public CreateConnectionThread(String name) {
super(name); super(name);
this.setDaemon(true); this.setDaemon(true);
} }
@ -2780,7 +2842,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
long lastDiscardCount = 0; long lastDiscardCount = 0;
int errorCount = 0; int errorCount = 0;
for (;;) { for (; ; ) {
// addLast // addLast
try { try {
lock.lockInterruptibly(); lock.lockInterruptibly();
@ -2829,6 +2891,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if ((!closing) && (!closed)) { if ((!closing) && (!closed)) {
LOG.error("create connection Thread Interrupted, url: " + jdbcUrl, e); LOG.error("create connection Thread Interrupted, url: " + jdbcUrl, e);
} }
DruidDataSource.this.doSomethingBeforeCreationThreadBreak();
break; break;
} finally { } finally {
lock.unlock(); lock.unlock();
@ -2838,9 +2901,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
try { try {
connection = createPhysicalConnection(); connection = createPhysicalConnection();
} catch (SQLException e) { } catch (SQLException | RuntimeException e) {
LOG.error("create connection SQLException, url: " + jdbcUrl + ", errorCode " + e.getErrorCode() if (e instanceof SQLException) {
+ ", state " + e.getSQLState(), e); LOG.error("create connection error, url: " + jdbcUrl + ", errorCode " + ((SQLException) e).getErrorCode()
+ ", state " + ((SQLException) e).getSQLState(), e);
} else {
LOG.error("create connection error", e);
}
errorCount++; errorCount++;
if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) { if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
@ -2861,17 +2928,16 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
try { try {
Thread.sleep(timeBetweenConnectErrorMillis); Thread.sleep(timeBetweenConnectErrorMillis);
} catch (InterruptedException interruptEx) { } catch (InterruptedException ignore) {
break;
} }
DruidDataSource.this.doSomethingBeforeCreationThreadBreak();
break;
} }
} catch (RuntimeException e) {
LOG.error("create connection RuntimeException", e);
setFailContinuous(true);
continue;
} catch (Error e) { } catch (Error e) {
LOG.error("create connection Error", e); LOG.error("create connection Error", e);
setFailContinuous(true); setFailContinuous(true);
DruidDataSource.this.doSomethingBeforeCreationThreadBreak();
break; break;
} }
@ -2892,11 +2958,49 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
} }
} }
public boolean isStarted() {
return started;
}
public void setStarted(boolean started) {
this.started = started;
}
}
//周期性检查生产线程状态,因为在终止生产线程的时候,为了不让生产线程疯狂重试数据库,只是生成了一个生产线程,但是并没有start,需要一个守护线程
//周期性检查线程状态,帮助其启动。
private class PeriodDetectionThread extends Thread {
public PeriodDetectionThread(String name) {
super(name);
this.setDaemon(true);
}
public void run() {
while (true) {
synchronized (DruidDataSource.this) {
//生产线程发生了切换,并且有线程在等待连接,需要主动唤醒生产线程,否则由getConnection方法来唤醒生产线程
if (!createConnectionThread.started && !destroyConnectionThread.started && notEmptyWaitThreadCount > 0) {
createConnectionThread.setStarted(true);
createConnectionThread.start();
destroyConnectionThread.setStarted(true);
destroyConnectionThread.start();
}
}
try {
Thread.sleep(30000);
} catch (InterruptedException ignore) {
break;
}
}
}
} }
public class DestroyConnectionThread extends Thread { public class DestroyConnectionThread extends Thread {
public DestroyConnectionThread(String name){ private volatile boolean started = true;
public DestroyConnectionThread(String name) {
super(name); super(name);
this.setDaemon(true); this.setDaemon(true);
} }
@ -2904,7 +3008,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
public void run() { public void run() {
initedLatch.countDown(); initedLatch.countDown();
for (;;) { for (; ; ) {
// 从前面开始删除 // 从前面开始删除
try { try {
if (closed || closing) { if (closed || closing) {
@ -2928,6 +3032,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
} }
public boolean isStarted() {
return started;
}
public void setStarted(boolean started) {
this.started = started;
}
} }
public class DestroyTask implements Runnable { public class DestroyTask implements Runnable {
@ -2948,14 +3059,14 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
public class LogStatsThread extends Thread { public class LogStatsThread extends Thread {
public LogStatsThread(String name){ public LogStatsThread(String name) {
super(name); super(name);
this.setDaemon(true); this.setDaemon(true);
} }
public void run() { public void run() {
try { try {
for (;;) { for (; ; ) {
try { try {
logStats(); logStats();
} catch (Exception e) { } catch (Exception e) {
@ -2981,7 +3092,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
try { try {
Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator(); Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();
for (; iter.hasNext();) { for (; iter.hasNext(); ) {
DruidPooledConnection pooledConnection = iter.next(); DruidPooledConnection pooledConnection = iter.next();
if (pooledConnection.isRunning()) { if (pooledConnection.isRunning()) {
@ -3033,7 +3144,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
buf.append("ownerThread current state is " + pooledConnection.getOwnerThread().getState() buf.append("ownerThread current state is " + pooledConnection.getOwnerThread().getState()
+ ", current stackTrace\n"); + ", current stackTrace\n");
trace = pooledConnection.getOwnerThread().getStackTrace(); trace = pooledConnection.getOwnerThread().getStackTrace();
for (int i = 0; i < trace.length; i++) { for (int i = 0; i < trace.length; i++) {
buf.append("\tat "); buf.append("\tat ");
@ -3049,7 +3160,9 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
return removeCount; return removeCount;
} }
/** Instance key */ /**
* Instance key
*/
protected String instanceKey = null; protected String instanceKey = null;
public Reference getReference() throws NamingException { public Reference getReference() throws NamingException {
@ -3119,7 +3232,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
int keepAliveCount = 0; int keepAliveCount = 0;
int fatalErrorIncrement = fatalErrorCount - fatalErrorCountLastShrink; int fatalErrorIncrement = fatalErrorCount - fatalErrorCountLastShrink;
fatalErrorCountLastShrink = fatalErrorCount; fatalErrorCountLastShrink = fatalErrorCount;
try { try {
if (!inited) { if (!inited) {
return; return;
@ -3130,7 +3243,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
for (int i = 0; i < poolingCount; ++i) { for (int i = 0; i < poolingCount; ++i) {
DruidConnectionHolder connection = connections[i]; DruidConnectionHolder connection = connections[i];
if ((onFatalError || fatalErrorIncrement > 0) && (lastFatalErrorTimeMillis > connection.connectTimeMillis)) { if ((onFatalError || fatalErrorIncrement > 0) && (lastFatalErrorTimeMillis > connection.connectTimeMillis)) {
keepAliveConnections[keepAliveCount++] = connection; keepAliveConnections[keepAliveCount++] = connection;
continue; continue;
} }
@ -3754,7 +3867,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
if (this.statLogger != null if (this.statLogger != null
&& (this.statLogger.getClass() == iface || DruidDataSourceStatLogger.class == iface)) { && (this.statLogger.getClass() == iface || DruidDataSourceStatLogger.class == iface)) {
return true; return true;
} }
@ -3770,7 +3883,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
if (this.statLogger != null if (this.statLogger != null
&& (this.statLogger.getClass() == iface || DruidDataSourceStatLogger.class == iface)) { && (this.statLogger.getClass() == iface || DruidDataSourceStatLogger.class == iface)) {
return (T) statLogger; return (T) statLogger;
} }
@ -3814,7 +3927,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
} }
int fillCount = 0; int fillCount = 0;
for (;;) { for (; ; ) {
try { try {
lock.lockInterruptibly(); lock.lockInterruptibly();
} catch (InterruptedException e) { } catch (InterruptedException e) {

28
fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/hssf/usermodel/HSSFCell.java

@ -221,8 +221,8 @@ public class HSSFCell extends CellBase {
BoolErrRecord boolErrRecord = ( BoolErrRecord ) record; BoolErrRecord boolErrRecord = ( BoolErrRecord ) record;
return boolErrRecord.isBoolean() return boolErrRecord.isBoolean()
? CellType.BOOLEAN ? CellType.BOOLEAN
: CellType.ERROR; : CellType.ERROR;
} }
throw new RuntimeException("Bad cell value rec (" + cval.getClass().getName() + ")"); throw new RuntimeException("Bad cell value rec (" + cval.getClass().getName() + ")");
} }
@ -412,7 +412,7 @@ public class HSSFCell extends CellBase {
throw new IllegalStateException("Invalid cell type: " + cellType); throw new IllegalStateException("Invalid cell type: " + cellType);
} }
if (cellType != _cellType && if (cellType != _cellType &&
_cellType != CellType._NONE ) // Special Value to indicate an uninitialized Cell _cellType != CellType._NONE ) // Special Value to indicate an uninitialized Cell
{ {
_sheet.getSheet().replaceValueRecord(_record); _sheet.getSheet().replaceValueRecord(_record);
} }
@ -643,7 +643,7 @@ public class HSSFCell extends CellBase {
private static RuntimeException typeMismatch(CellType expectedTypeCode, CellType actualTypeCode, boolean isFormulaCell) { private static RuntimeException typeMismatch(CellType expectedTypeCode, CellType actualTypeCode, boolean isFormulaCell) {
String msg = "Cannot get a " + expectedTypeCode + " value from a " + actualTypeCode String msg = "Cannot get a " + expectedTypeCode + " value from a " + actualTypeCode
+ " " + (isFormulaCell ? "formula " : "") + "cell"; + " " + (isFormulaCell ? "formula " : "") + "cell";
return new IllegalStateException(msg); return new IllegalStateException(msg);
} }
private static void checkFormulaCachedValueType(CellType expectedTypeCode, FormulaRecord fr) { private static void checkFormulaCachedValueType(CellType expectedTypeCode, FormulaRecord fr) {
@ -723,8 +723,8 @@ public class HSSFCell extends CellBase {
*/ */
public String getStringCellValue() public String getStringCellValue()
{ {
HSSFRichTextString str = getRichStringCellValue(); HSSFRichTextString str = getRichStringCellValue();
return str.getString(); return str.getString();
} }
/** /**
@ -863,7 +863,7 @@ public class HSSFCell extends CellBase {
case NUMERIC: case NUMERIC:
return NumberToTextConverter.toText(((NumberRecord)_record).getValue()); return NumberToTextConverter.toText(((NumberRecord)_record).getValue());
case ERROR: case ERROR:
return FormulaError.forInt(((BoolErrRecord)_record).getErrorValue()).getString(); return FormulaError.forInt(((BoolErrRecord)_record).getErrorValue()).getString();
case FORMULA: case FORMULA:
// should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator // should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator
// just use cached formula result instead // just use cached formula result instead
@ -970,9 +970,9 @@ public class HSSFCell extends CellBase {
*/ */
public HSSFCellStyle getCellStyle() public HSSFCellStyle getCellStyle()
{ {
short styleIndex=_record.getXFIndex(); short styleIndex=_record.getXFIndex();
ExtendedFormatRecord xf = _book.getWorkbook().getExFormatAt(styleIndex); ExtendedFormatRecord xf = _book.getWorkbook().getExFormatAt(styleIndex);
return new HSSFCellStyle(styleIndex, xf, _book); return new HSSFCellStyle(styleIndex, xf, _book);
} }
/** /**
@ -1038,7 +1038,7 @@ public class HSSFCell extends CellBase {
sdf.setTimeZone(LocaleUtil.getUserTimeZone()); sdf.setTimeZone(LocaleUtil.getUserTimeZone());
return sdf.format(getDateCellValue()); return sdf.format(getDateCellValue());
} }
return String.valueOf(getNumericCellValue()); return String.valueOf(getNumericCellValue());
case STRING: case STRING:
return getStringCellValue(); return getStringCellValue();
default: default:
@ -1069,7 +1069,7 @@ public class HSSFCell extends CellBase {
* *
* @return comment associated with this cell * @return comment associated with this cell
*/ */
public HSSFComment getCellComment(){ public HSSFComment getCellComment(){
if (_comment == null) { if (_comment == null) {
_comment = _sheet.findCellComment(_record.getRow(), _record.getColumn()); _comment = _sheet.findCellComment(_record.getRow(), _record.getColumn());
} }
@ -1258,5 +1258,9 @@ public class HSSFCell extends CellBase {
return styleIndex; return styleIndex;
} }
public boolean isRichText() {
return false;
}
} }

8
fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/ss/usermodel/Cell.java

@ -71,7 +71,7 @@ public interface Cell {
* *
* @return the Row that owns this cell * @return the Row that owns this cell
*/ */
Row getRow(); Row getRow();
/** /**
* Set the cells type (blank, numeric, boolean, error or string). * Set the cells type (blank, numeric, boolean, error or string).
@ -253,7 +253,7 @@ public interface Cell {
*/ */
void setCellValue(String value); void setCellValue(String value);
boolean isRichText();
/** /**
* Sets formula for this cell. * Sets formula for this cell.
* <p>If {@code formula} is not null, sets or updates the formula. If {@code formula} is null, removes the formula. * <p>If {@code formula} is not null, sets or updates the formula. If {@code formula} is null, removes the formula.
@ -355,7 +355,7 @@ public interface Cell {
* precalculated value, for booleans we'll set its value. For other types we * precalculated value, for booleans we'll set its value. For other types we
* will change the cell to a boolean cell and set its value. * will change the cell to a boolean cell and set its value.
*/ */
void setCellValue(boolean value); void setCellValue(boolean value);
/** /**
* Set a error value for the cell * Set a error value for the cell
@ -419,7 +419,7 @@ public interface Cell {
*/ */
void setAsActiveCell(); void setAsActiveCell();
/** /**
* Gets the address of this cell * Gets the address of this cell
* *
* @return <code>A1</code> style address of this cell * @return <code>A1</code> style address of this cell

5
fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/xssf/streaming/SXSSFCell.java

@ -741,6 +741,11 @@ public class SXSSFCell extends CellBase {
} }
} }
public boolean isRichText() {
CellType cellType = this.getCellType();
return cellType == CellType.STRING ? ((SXSSFCell.StringValue)this._value).isRichText() : false;
}
@Override @Override
public void setCellValue(BigInteger value) { public void setCellValue(BigInteger value) {
ensureTypeOrFormulaType(CellType.NUMERIC_BIG_INTEGER); ensureTypeOrFormulaType(CellType.NUMERIC_BIG_INTEGER);

192
fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/xssf/streaming/SheetDataWriter.java

@ -202,196 +202,198 @@ public class SheetDataWriter implements Closeable {
_numberLastFlushedRow = Math.max(rownum, _numberLastFlushedRow); _numberLastFlushedRow = Math.max(rownum, _numberLastFlushedRow);
_numberOfCellsOfLastFlushedRow = row.getLastCellNum(); _numberOfCellsOfLastFlushedRow = row.getLastCellNum();
_numberOfFlushedRows++; _numberOfFlushedRows++;
beginRow(rownum, row); int size = this._numberOfCellsOfLastFlushedRow > 0 ? this._numberOfCellsOfLastFlushedRow : 1;
StringBuilder sb = new StringBuilder(size << 6);
beginRow(rownum, row, sb);
Iterator<Cell> cells = row.allCellsIterator(); Iterator<Cell> cells = row.allCellsIterator();
int columnIndex = 0; int columnIndex = 0;
while (cells.hasNext()) { while (cells.hasNext()) {
writeCell(columnIndex++, cells.next()); writeCell(columnIndex++, cells.next(),sb);
} }
endRow(); endRow(sb);
this._out.write(sb.toString());
} }
void beginRow(int rownum, SXSSFRow row) throws IOException { void beginRow(int rownum, SXSSFRow row,StringBuilder sb) throws IOException {
_out.write("<row"); sb.append("<row");
writeAttribute("r", Integer.toString(rownum + 1)); writeAttribute("r", Integer.toString(rownum + 1), sb);
if (row.hasCustomHeight()) { if (row.hasCustomHeight()) {
writeAttribute("customHeight", "true"); writeAttribute("customHeight", "true", sb);
writeAttribute("ht", Float.toString(row.getHeightInPoints())); writeAttribute("ht", Float.toString(row.getHeightInPoints()), sb);
} }
if (row.getZeroHeight()) { if (row.getZeroHeight()) {
writeAttribute("hidden", "true"); writeAttribute("hidden", "true", sb);
} }
if (row.isFormatted()) { if (row.isFormatted()) {
writeAttribute("s", Integer.toString(row.getRowStyleIndex())); writeAttribute("s", Integer.toString(row.getRowStyleIndex()), sb);
writeAttribute("customFormat", "1"); writeAttribute("customFormat", "1", sb);
} }
if (row.getOutlineLevel() != 0) { if (row.getOutlineLevel() != 0) {
writeAttribute("outlineLevel", Integer.toString(row.getOutlineLevel())); writeAttribute("outlineLevel", Integer.toString(row.getOutlineLevel()), sb);
} }
if (row.getHidden() != null) { if (row.getHidden() != null) {
writeAttribute("hidden", row.getHidden() ? "1" : "0"); writeAttribute("hidden", row.getHidden() ? "1" : "0", sb);
} }
if (row.getCollapsed() != null) { if (row.getCollapsed() != null) {
writeAttribute("collapsed", row.getCollapsed() ? "1" : "0"); writeAttribute("collapsed", row.getCollapsed() ? "1" : "0", sb);
} }
_out.write(">\n"); sb.append(">\n");
this._rownum = rownum; this._rownum = rownum;
} }
void endRow() throws IOException { void endRow(StringBuilder sb) throws IOException {
_out.write("</row>\n"); sb.append("</row>\n");
} }
public void writeCell(int columnIndex, Cell cell) throws IOException { public void writeCell(int columnIndex, Cell cell,StringBuilder sb) throws IOException {
if (cell == null) { if (cell == null) {
return; return;
} }
String ref = new CellReference(_rownum, columnIndex).formatAsString(); String ref = new CellReference(_rownum, columnIndex).formatAsString();
_out.write("<c"); sb.append("<c");
writeAttribute("r", ref); writeAttribute("r", ref,sb);
CellStyle cellStyle = cell.getCellStyle(); CellStyle cellStyle = cell.getCellStyle();
if (cellStyle.getIndex() != 0) { if (cellStyle.getIndex() != 0) {
// need to convert the short to unsigned short as the indexes can be up to 64k // need to convert the short to unsigned short as the indexes can be up to 64k
// ideally we would use int for this index, but that would need changes to some more // ideally we would use int for this index, but that would need changes to some more
// APIs // APIs
writeAttribute("s", Integer.toString(cellStyle.getIndex() & 0xffff)); writeAttribute("s", Integer.toString(cellStyle.getIndex() & 0xffff),sb);
} }
CellType cellType = cell.getCellType(); CellType cellType = cell.getCellType();
switch (cellType) { switch (cellType) {
case BLANK: { case BLANK: {
_out.write('>'); sb.append('>');
break; break;
} }
case FORMULA: { case FORMULA: {
switch (cell.getCachedFormulaResultType()) { switch (cell.getCachedFormulaResultType()) {
case NUMERIC: case NUMERIC:
writeAttribute("t", "n"); writeAttribute("t", "n",sb);
break; break;
case STRING: case STRING:
writeAttribute("t", STCellType.STR.toString()); writeAttribute("t", STCellType.STR.toString(),sb);
break; break;
case BOOLEAN: case BOOLEAN:
writeAttribute("t", "b"); writeAttribute("t", "b",sb);
break; break;
case ERROR: case ERROR:
writeAttribute("t", "e"); writeAttribute("t", "e",sb);
break; break;
} }
_out.write("><f>"); sb.append("><f>");
outputQuotedString(cell.getCellFormula()); outputQuotedString(cell.getCellFormula(),sb);
_out.write("</f>"); sb.append("</f>");
switch (cell.getCachedFormulaResultType()) { switch (cell.getCachedFormulaResultType()) {
case NUMERIC: case NUMERIC:
double nval = cell.getNumericCellValue(); double nval = cell.getNumericCellValue();
if (!Double.isNaN(nval)) { if (!Double.isNaN(nval)) {
_out.write("<v>"); sb.append("<v>");
_out.write(Double.toString(nval)); sb.append(Double.toString(nval));
_out.write("</v>"); sb.append("</v>");
} }
break; break;
case STRING: case STRING:
String value = cell.getStringCellValue(); String value = cell.getStringCellValue();
if (value != null && !value.isEmpty()) { if (value != null && !value.isEmpty()) {
_out.write("<v>"); sb.append("<v>");
_out.write(value); sb.append(value);
_out.write("</v>"); sb.append("</v>");
} }
break; break;
case BOOLEAN: case BOOLEAN:
_out.write("><v>"); sb.append("><v>");
_out.write(cell.getBooleanCellValue() ? "1" : "0"); sb.append(cell.getBooleanCellValue() ? "1" : "0");
_out.write("</v>"); sb.append("</v>");
break; break;
case ERROR: { case ERROR: {
FormulaError error = FormulaError.forInt(cell.getErrorCellValue()); FormulaError error = FormulaError.forInt(cell.getErrorCellValue());
_out.write("><v>"); sb.append("><v>");
_out.write(error.getString()); sb.append(error.getString());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
} }
break; break;
} }
case STRING: { case STRING: {
if (_sharedStringSource != null) { if (_sharedStringSource != null&& cell.isRichText()) {
//XSSFRichTextString rt = new XSSFRichTextString(cell.getStringCellValue());
RichTextString rt = cell.getRichStringCellValue(); RichTextString rt = cell.getRichStringCellValue();
int sRef = _sharedStringSource.addSharedStringItem(rt); int sRef = _sharedStringSource.addSharedStringItem(rt);
writeAttribute("t", STCellType.S.toString()); writeAttribute("t", STCellType.S.toString(),sb);
_out.write("><v>"); sb.append("><v>");
_out.write(String.valueOf(sRef)); sb.append(String.valueOf(sRef));
_out.write("</v>"); sb.append("</v>");
} else { } else {
writeAttribute("t", "inlineStr"); writeAttribute("t", "inlineStr",sb);
_out.write("><is><t"); sb.append("><is><t");
if (hasLeadingTrailingSpaces(cell.getStringCellValue())) { if (hasLeadingTrailingSpaces(cell.getStringCellValue())) {
writeAttribute("xml:space", "preserve"); writeAttribute("xml:space", "preserve",sb);
} }
_out.write(">"); sb.append(">");
outputQuotedString(cell.getStringCellValue()); outputQuotedString(cell.getStringCellValue(),sb);
_out.write("</t></is>"); sb.append("</t></is>");
} }
break; break;
} }
case NUMERIC_STRING: { case NUMERIC_STRING: {
_out.write(" t=\"n\"><v>"); sb.append(" t=\"n\"><v>");
_out.write(cell.getNumericStringCellValue()); sb.append(cell.getNumericStringCellValue());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case NUMERIC_BIG_DECIMAL: { case NUMERIC_BIG_DECIMAL: {
_out.write(" t=\"n\">"); sb.append(" t=\"n\">");
_out.write("<v>"); sb.append("<v>");
_out.write(cell.getNumericBigDecimalCellValue().toString()); sb.append(cell.getNumericBigDecimalCellValue().toString());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case NUMERIC_BIG_INTEGER: { case NUMERIC_BIG_INTEGER: {
_out.write(" t=\"n\">"); sb.append(" t=\"n\">");
_out.write("<v>"); sb.append("<v>");
_out.write(cell.getNumericBigIntegerCellValue().toString()); sb.append(cell.getNumericBigIntegerCellValue().toString());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case NUMERIC: { case NUMERIC: {
writeAttribute("t", "n"); writeAttribute("t", "n",sb);
_out.write("><v>"); sb.append("><v>");
_out.write(Double.toString(cell.getNumericCellValue())); sb.append(Double.toString(cell.getNumericCellValue()));
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case BOOLEAN: { case BOOLEAN: {
writeAttribute("t", "b"); writeAttribute("t", "b",sb);
_out.write("><v>"); sb.append("><v>");
_out.write(cell.getBooleanCellValue() ? "1" : "0"); sb.append(cell.getBooleanCellValue() ? "1" : "0");
_out.write("</v>"); sb.append("</v>");
break; break;
} }
case ERROR: { case ERROR: {
FormulaError error = FormulaError.forInt(cell.getErrorCellValue()); FormulaError error = FormulaError.forInt(cell.getErrorCellValue());
writeAttribute("t", "e"); writeAttribute("t", "e",sb);
_out.write("><v>"); sb.append("><v>");
_out.write(error.getString()); sb.append(error.getString());
_out.write("</v>"); sb.append("</v>");
break; break;
} }
default: { default: {
throw new IllegalStateException("Invalid cell type: " + cellType); throw new IllegalStateException("Invalid cell type: " + cellType);
} }
} }
_out.write("</c>"); sb.append("</c>");
} }
private void writeAttribute(String name, String value) throws IOException { private void writeAttribute(String name, String value,StringBuilder sb) throws IOException {
_out.write(' '); sb.append(' ');
_out.write(name); sb.append(name);
_out.write("=\""); sb.append("=\"");
_out.write(value); sb.append(value);
_out.write('\"'); sb.append('\"');
} }
/** /**
@ -407,7 +409,7 @@ public class SheetDataWriter implements Closeable {
return false; return false;
} }
protected void outputQuotedString(String s) throws IOException { protected void outputQuotedString(String s,StringBuilder sb) throws IOException {
if (s == null || s.length() == 0) { if (s == null || s.length() == 0) {
return; return;
} }
@ -415,29 +417,29 @@ public class SheetDataWriter implements Closeable {
for (String codepoint : new StringCodepointsIterable(s)) { for (String codepoint : new StringCodepointsIterable(s)) {
switch (codepoint) { switch (codepoint) {
case "<": case "<":
_out.write("&lt;"); sb.append("&lt;");
break; break;
case ">": case ">":
_out.write("&gt;"); sb.append("&gt;");
break; break;
case "&": case "&":
_out.write("&amp;"); sb.append("&amp;");
break; break;
case "\"": case "\"":
_out.write("&quot;"); sb.append("&quot;");
break; break;
// Special characters // Special characters
case "\n": case "\n":
_out.write("&#xa;"); sb.append("&#xa;");
break; break;
case "\r": case "\r":
_out.write("&#xd;"); sb.append("&#xd;");
break; break;
case "\t": case "\t":
_out.write("&#x9;"); sb.append("&#x9;");
break; break;
case "\u00A0": // NO-BREAK SPACE case "\u00A0": // NO-BREAK SPACE
_out.write("&#xa0;"); sb.append("&#xa0;");
break; break;
default: default:
if (codepoint.length() == 1) { if (codepoint.length() == 1) {
@ -445,12 +447,12 @@ public class SheetDataWriter implements Closeable {
// YK: XmlBeans silently replaces all ISO control characters ( < 32) with question marks. // YK: XmlBeans silently replaces all ISO control characters ( < 32) with question marks.
// the same rule applies to "not a character" symbols. // the same rule applies to "not a character" symbols.
if (replaceWithQuestionMark(c)) { if (replaceWithQuestionMark(c)) {
_out.write('?'); sb.append('?');
} else { } else {
_out.write(c); sb.append(c);
} }
} else { } else {
_out.write(codepoint); sb.append(codepoint);
} }
break; break;
} }

68
fine-poi/src/main/java/com/fr/third/v2/org/apache/poi/xssf/usermodel/XSSFCell.java

@ -138,9 +138,9 @@ public final class XSSFCell extends CellBase {
/** /**
* Copy cell value, formula and style, from srcCell per cell copy policy * Copy cell value, formula and style, from srcCell per cell copy policy
* If srcCell is null, clears the cell value and cell style per cell copy policy * If srcCell is null, clears the cell value and cell style per cell copy policy
* *
* This does not shift references in formulas. Use {@link com.fr.third.v2.org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter} to shift references in formulas. * This does not shift references in formulas. Use {@link com.fr.third.v2.org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter} to shift references in formulas.
* *
* @param srcCell The cell to take value, formula and style from * @param srcCell The cell to take value, formula and style from
* @param policy The policy for copying the information, see {@link CellCopyPolicy} * @param policy The policy for copying the information, see {@link CellCopyPolicy}
* @throws IllegalArgumentException if copy cell style and srcCell is from a different workbook * @throws IllegalArgumentException if copy cell style and srcCell is from a different workbook
@ -190,12 +190,12 @@ public final class XSSFCell extends CellBase {
setBlank(); setBlank();
} }
} }
// Copy CellStyle // Copy CellStyle
if (policy.isCopyCellStyle()) { if (policy.isCopyCellStyle()) {
setCellStyle(srcCell == null ? null : srcCell.getCellStyle()); setCellStyle(srcCell == null ? null : srcCell.getCellStyle());
} }
final Hyperlink srcHyperlink = (srcCell == null) ? null : srcCell.getHyperlink(); final Hyperlink srcHyperlink = (srcCell == null) ? null : srcCell.getHyperlink();
if (policy.isMergeHyperlink()) { if (policy.isMergeHyperlink()) {
@ -301,17 +301,17 @@ public final class XSSFCell extends CellBase {
return 0.0; return 0.0;
case NUMERIC: case NUMERIC:
if(_cell.isSetV()) { if(_cell.isSetV()) {
String v = _cell.getV(); String v = _cell.getV();
if (v.isEmpty()) { if (v.isEmpty()) {
return 0.0; return 0.0;
} }
try { try {
return Double.parseDouble(v); return Double.parseDouble(v);
} catch(NumberFormatException e) { } catch(NumberFormatException e) {
throw typeMismatch(CellType.NUMERIC, CellType.STRING, false); throw typeMismatch(CellType.NUMERIC, CellType.STRING, false);
} }
} else { } else {
return 0.0; return 0.0;
} }
case FORMULA: case FORMULA:
throw new AssertionError(); throw new AssertionError();
@ -441,7 +441,7 @@ public final class XSSFCell extends CellBase {
// existing behavior - create a new XSSFEvaluationWorkbook for every call // existing behavior - create a new XSSFEvaluationWorkbook for every call
return getCellFormula(null); return getCellFormula(null);
} }
/** /**
* package/hierarchy use only - reuse an existing evaluation workbook if available for caching * package/hierarchy use only - reuse an existing evaluation workbook if available for caching
* *
@ -627,7 +627,7 @@ public final class XSSFCell extends CellBase {
* *
* <p>To change the style of a cell without affecting other cells that use the same style, * <p>To change the style of a cell without affecting other cells that use the same style,
* use {@link com.fr.third.v2.org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, java.util.Map)}</p> * use {@link com.fr.third.v2.org.apache.poi.ss.util.CellUtil#setCellStyleProperties(Cell, java.util.Map)}</p>
* *
* @param style reference contained in the workbook. * @param style reference contained in the workbook.
* If the value is null then the style information is removed causing the cell to used the default workbook style. * If the value is null then the style information is removed causing the cell to used the default workbook style.
* @throws IllegalArgumentException if style belongs to a different styles source (most likely because style is from a different Workbook) * @throws IllegalArgumentException if style belongs to a different styles source (most likely because style is from a different Workbook)
@ -646,7 +646,7 @@ public final class XSSFCell extends CellBase {
_cell.setS(idx); _cell.setS(idx);
} }
} }
/** /**
* POI currently supports these formula types: * POI currently supports these formula types:
* <ul> * <ul>
@ -663,7 +663,7 @@ public final class XSSFCell extends CellBase {
} }
return false; return false;
} }
/** /**
* Return the cell type. Tables in an array formula return * Return the cell type. Tables in an array formula return
* {@link CellType#FORMULA} for all cells, even though the formula is only defined * {@link CellType#FORMULA} for all cells, even though the formula is only defined
@ -697,7 +697,7 @@ public final class XSSFCell extends CellBase {
return getBaseCellType(false); return getBaseCellType(false);
} }
/** /**
* Only valid for formula cells * Only valid for formula cells
* @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING},
@ -736,7 +736,7 @@ public final class XSSFCell extends CellBase {
case STCellType.INT_S: // String is in shared strings case STCellType.INT_S: // String is in shared strings
case STCellType.INT_INLINE_STR: // String is inline in cell case STCellType.INT_INLINE_STR: // String is inline in cell
case STCellType.INT_STR: case STCellType.INT_STR:
return CellType.STRING; return CellType.STRING;
default: default:
throw new IllegalStateException("Illegal cell type: " + this._cell.getT()); throw new IllegalStateException("Illegal cell type: " + this._cell.getT());
} }
@ -915,7 +915,7 @@ public final class XSSFCell extends CellBase {
protected void setCellTypeImpl(CellType cellType) { protected void setCellTypeImpl(CellType cellType) {
setCellType(cellType, null); setCellType(cellType, null);
} }
/** /**
* Needed by bug #62834, which points out getCellFormula() expects an evaluation context or creates a new one, * Needed by bug #62834, which points out getCellFormula() expects an evaluation context or creates a new one,
* so if there is one in use, it needs to be carried on through. * so if there is one in use, it needs to be carried on through.
@ -1076,7 +1076,7 @@ public final class XSSFCell extends CellBase {
/** /**
* Removes the comment for this cell, if there is one. * Removes the comment for this cell, if there is one.
*/ */
@Override @Override
public void removeCellComment() { public void removeCellComment() {
XSSFComment comment = getCellComment(); XSSFComment comment = getCellComment();
@ -1138,10 +1138,10 @@ public final class XSSFCell extends CellBase {
public CTCell getCTCell(){ public CTCell getCTCell(){
return _cell; return _cell;
} }
/** /**
* Set a new internal xml bean. This is only for internal use, do not call this from outside! * Set a new internal xml bean. This is only for internal use, do not call this from outside!
* *
* This is necessary in some rare cases to work around XMLBeans specialties. * This is necessary in some rare cases to work around XMLBeans specialties.
*/ */
@Internal @Internal
@ -1179,7 +1179,7 @@ public final class XSSFCell extends CellBase {
// fall-through // fall-through
case BLANK: case BLANK:
return false; return false;
default: default:
throw new RuntimeException("Unexpected cell type (" + cellType + ")"); throw new RuntimeException("Unexpected cell type (" + cellType + ")");
} }
@ -1218,19 +1218,19 @@ public final class XSSFCell extends CellBase {
return FALSE; return FALSE;
} }
throw new IllegalStateException("Unexpected boolean cached formula value '" throw new IllegalStateException("Unexpected boolean cached formula value '"
+ textValue + "'."); + textValue + "'.");
case STRING: case STRING:
// fall-through // fall-through
case NUMERIC: case NUMERIC:
// fall-through // fall-through
case ERROR: case ERROR:
return textValue; return textValue;
default: default:
throw new IllegalStateException("Unexpected formula result type (" + cellType + ")"); throw new IllegalStateException("Unexpected formula result type (" + cellType + ")");
} }
} }
@Override @Override
@ -1257,14 +1257,18 @@ public final class XSSFCell extends CellBase {
CalculationChain calcChain = getSheet().getWorkbook().getCalculationChain(); CalculationChain calcChain = getSheet().getWorkbook().getCalculationChain();
int sheetId = Math.toIntExact(getSheet().sheet.getSheetId()); int sheetId = Math.toIntExact(getSheet().sheet.getSheetId());
//remove the reference in the calculation chain //remove the reference in the calculation chain
if(calcChain != null) calcChain.removeItem(sheetId, getReference()); if(calcChain != null) calcChain.removeItem(sheetId, getReference());
CTCell ctCell = getCTCell(); CTCell ctCell = getCTCell();
String r = new CellReference(getRowIndex(), getColumnIndex()).formatAsString(); String r = new CellReference(getRowIndex(), getColumnIndex()).formatAsString();
ctCell.setR(r); ctCell.setR(r);
} }
public boolean isRichText() {
return false;
}
} }

Loading…
Cancel
Save