Browse Source
* 'feature/10.0' of http://cloud.finedevelop.com:2015/scm/~xiaoxia/design: REPORT-15314 103模板信息收集=>调整代码 REPORT-15314 103模板信息收集=>考虑放假的情况 REPORT-15314 103模板信息收集=>精确度提升research/10.0
XiaXiang
6 years ago
9 changed files with 427 additions and 52 deletions
@ -0,0 +1,117 @@ |
|||||||
|
package com.fr.design.mainframe.template.info; |
||||||
|
|
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.xml.XMLPrintWriter; |
||||||
|
import com.fr.stable.xml.XMLReadable; |
||||||
|
import com.fr.stable.xml.XMLWriter; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
|
||||||
|
import java.text.ParseException; |
||||||
|
import java.text.SimpleDateFormat; |
||||||
|
import java.util.Calendar; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
|
||||||
|
/** |
||||||
|
* 管理打开设计器的日期记录 |
||||||
|
* Created by plough on 2019/4/19. |
||||||
|
*/ |
||||||
|
class DesignerOpenHistory implements XMLReadable, XMLWriter { |
||||||
|
static final String XML_TAG = "DesignerOpenHistory"; |
||||||
|
private static DesignerOpenHistory singleton; |
||||||
|
private static final String SPLITTER = ","; |
||||||
|
private static final int LENGTH = 3; // 保留最近 3 次的记录
|
||||||
|
// 最近的日期是 history[0],最早的日期是 history[LENGTH-1]
|
||||||
|
private String[] history = new String[LENGTH]; |
||||||
|
|
||||||
|
private DesignerOpenHistory() { |
||||||
|
for (int i = 0; i < LENGTH; i++) { |
||||||
|
history[i] = StringUtils.EMPTY; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static DesignerOpenHistory getInstance() { |
||||||
|
if (singleton == null) { |
||||||
|
singleton = new DesignerOpenHistory(); |
||||||
|
} |
||||||
|
return singleton; |
||||||
|
} |
||||||
|
|
||||||
|
void update() { |
||||||
|
String today = getToday(); |
||||||
|
if (ComparatorUtils.equals(history[0], today)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
shiftByOne(); |
||||||
|
history[0] = today; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取历史记录中囊括的日子数。即最早的历史记录 history[LENGTH - 1],到最晚的记录 history[0] 之间的时间跨度 |
||||||
|
*/ |
||||||
|
int getHistorySpanDayCount() { |
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
||||||
|
try { |
||||||
|
Date earliestDate = sdf.parse(getEarliestDate()); |
||||||
|
Date latestDate = sdf.parse(history[0]); |
||||||
|
long diffInMillies = latestDate.getTime() - earliestDate.getTime(); |
||||||
|
return (int)TimeUnit.DAYS.convert(diffInMillies,TimeUnit.MILLISECONDS) + 1; |
||||||
|
} catch (ParseException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 今天是否已经打开过设计器 |
||||||
|
*/ |
||||||
|
boolean hasOpenedToday() { |
||||||
|
String today = getToday(); |
||||||
|
return ComparatorUtils.equals(today, history[0]); |
||||||
|
} |
||||||
|
|
||||||
|
private String getEarliestDate() { |
||||||
|
for (int i = LENGTH - 1; i >= 0; i--) { |
||||||
|
if (StringUtils.isNotEmpty(history[i])) { |
||||||
|
return history[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new AssertionError("Designer open history is empty!"); |
||||||
|
} |
||||||
|
|
||||||
|
private void shiftByOne() { |
||||||
|
for (int i = LENGTH - 1; i > 0; i--) { |
||||||
|
history[i] = history[i-1]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private String getToday() { |
||||||
|
return new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return StringUtils.join(SPLITTER, history); |
||||||
|
} |
||||||
|
|
||||||
|
private void parseString(String s) { |
||||||
|
String[] arr = s.split(SPLITTER); |
||||||
|
System.arraycopy(arr, 0, history, 0, arr.length); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void readXML(XMLableReader reader) { |
||||||
|
if (XML_TAG.equals(reader.getTagName())) { |
||||||
|
parseString(reader.getElementValue()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void writeXML(XMLPrintWriter writer) { |
||||||
|
writer.startTAG(XML_TAG); |
||||||
|
writer.textNode(toString()); |
||||||
|
writer.end(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
package com.fr.design.mainframe.template.info; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2019/4/19. |
||||||
|
*/ |
||||||
|
public class TimeConsumeTimer { |
||||||
|
private static final int ONE_THOUSAND = 1000; |
||||||
|
private enum State { |
||||||
|
RUNNING, STOPPED |
||||||
|
} |
||||||
|
private int timeConsume; // 单位 s
|
||||||
|
private long startMS; // 单位 ms
|
||||||
|
private long stopMS; |
||||||
|
private State state; |
||||||
|
private boolean enabled; |
||||||
|
|
||||||
|
public TimeConsumeTimer() { |
||||||
|
reset(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isEnabled() { |
||||||
|
return enabled; |
||||||
|
} |
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) { |
||||||
|
this.enabled = enabled; |
||||||
|
} |
||||||
|
|
||||||
|
public void start() { |
||||||
|
if (!isEnabled() || isRunning()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
startMS = System.currentTimeMillis(); |
||||||
|
state = State.RUNNING; |
||||||
|
} |
||||||
|
|
||||||
|
public void stop() { |
||||||
|
if (!isEnabled() || !isRunning()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
stopMS = System.currentTimeMillis(); |
||||||
|
|
||||||
|
timeConsume += ((stopMS - startMS) / ONE_THOUSAND); |
||||||
|
startMS = 0; |
||||||
|
stopMS = 0; |
||||||
|
state = State.STOPPED; |
||||||
|
} |
||||||
|
|
||||||
|
public int popTime() { |
||||||
|
if (!isEnabled()) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
stop(); |
||||||
|
int result = timeConsume; |
||||||
|
reset(); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean isRunning() { |
||||||
|
return state == State.RUNNING; |
||||||
|
} |
||||||
|
|
||||||
|
private void reset() { |
||||||
|
timeConsume = 0; |
||||||
|
startMS = 0; |
||||||
|
stopMS = 0; |
||||||
|
state = State.STOPPED; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,108 @@ |
|||||||
|
package com.fr.design.mainframe.template.info; |
||||||
|
|
||||||
|
import com.fr.invoke.Reflect; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.xml.XMLPrintWriter; |
||||||
|
import com.fr.stable.xml.XMLableReader; |
||||||
|
import com.fr.third.javax.xml.stream.XMLStreamException; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import java.io.PrintWriter; |
||||||
|
import java.io.StringReader; |
||||||
|
import java.io.StringWriter; |
||||||
|
import java.text.SimpleDateFormat; |
||||||
|
import java.util.Calendar; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals; |
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertFalse; |
||||||
|
import static org.junit.Assert.assertTrue; |
||||||
|
import static org.junit.Assert.fail; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2019/4/21. |
||||||
|
*/ |
||||||
|
public class DesignerOpenHistoryTest { |
||||||
|
private DesignerOpenHistory openHistory; |
||||||
|
private String[] mockHistory = new String[] { |
||||||
|
"2019-04-08", "2019-04-03", "2019-03-29" |
||||||
|
}; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() { |
||||||
|
openHistory = DesignerOpenHistory.getInstance(); |
||||||
|
Reflect.on(openHistory).set("history", mockHistory); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testReadAndWrite() throws XMLStreamException { |
||||||
|
// 写入 xml
|
||||||
|
StringWriter sw = new StringWriter(); |
||||||
|
XMLPrintWriter writer = XMLPrintWriter.create(new PrintWriter(sw)); |
||||||
|
openHistory.writeXML(writer); |
||||||
|
writer.flush(); |
||||||
|
writer.close(); |
||||||
|
|
||||||
|
String xmlText = sw.getBuffer().toString(); |
||||||
|
|
||||||
|
// 临时修改配置
|
||||||
|
Reflect.on(openHistory).set("history", new String[] {"", "", ""}); |
||||||
|
|
||||||
|
// 从 xml 中读取
|
||||||
|
StringReader sr = new StringReader(xmlText); |
||||||
|
XMLableReader xmlReader = XMLableReader.createXMLableReader(sr); |
||||||
|
xmlReader.readXMLObject(openHistory); |
||||||
|
|
||||||
|
// 验证:与写入时的配置一致
|
||||||
|
assertArrayEquals(mockHistory, (String[])Reflect.on(openHistory).field("history").get()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testToString() { |
||||||
|
assertEquals("2019-04-08,2019-04-03,2019-03-29", openHistory.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testParseString() { |
||||||
|
String[] mockDates = {"2020-04-08", "2019-04-03", "2016-03-29"}; |
||||||
|
Reflect.on(openHistory).call("parseString", StringUtils.join(",", mockDates)); |
||||||
|
assertArrayEquals(mockDates, (String[])Reflect.on(openHistory).field("history").get()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testGetHistorySpanDayCount() { |
||||||
|
assertEquals(11, openHistory.getHistorySpanDayCount()); |
||||||
|
|
||||||
|
Reflect.on(openHistory).set("history", new String[] {"2019-05-03", "2019-05-02", ""}); |
||||||
|
assertEquals(2, openHistory.getHistorySpanDayCount()); |
||||||
|
|
||||||
|
Reflect.on(openHistory).set("history", new String[] {"2019-05-03", "", ""}); |
||||||
|
assertEquals(1, openHistory.getHistorySpanDayCount()); |
||||||
|
|
||||||
|
try { |
||||||
|
Reflect.on(openHistory).set("history", new String[] {"", "", ""}); |
||||||
|
fail("should not be here"); |
||||||
|
} catch (AssertionError ignore) { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testHasOpenedToday() { |
||||||
|
assertFalse(openHistory.hasOpenedToday()); |
||||||
|
|
||||||
|
Reflect.on(openHistory).set("history", new String[] {getToday(), "2019-02-02", ""}); |
||||||
|
assertTrue(openHistory.hasOpenedToday()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testUpdate() { |
||||||
|
openHistory.update(); |
||||||
|
String[] arr = { getToday(), "2019-04-08", "2019-04-03" }; |
||||||
|
assertArrayEquals(arr, (String[])Reflect.on(openHistory).field("history").get()); |
||||||
|
} |
||||||
|
|
||||||
|
private String getToday() { |
||||||
|
return new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
package com.fr.design.mainframe.template.info; |
||||||
|
|
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by plough on 2019/4/19. |
||||||
|
*/ |
||||||
|
public class TimeConsumeTimerTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testNotEnabled() throws InterruptedException { |
||||||
|
TimeConsumeTimer consumeTimer = new TimeConsumeTimer(); |
||||||
|
consumeTimer.start(); |
||||||
|
Thread.sleep(1100); |
||||||
|
consumeTimer.stop(); |
||||||
|
assertEquals(0, consumeTimer.popTime()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testEnabled() throws InterruptedException { |
||||||
|
TimeConsumeTimer consumeTimer = new TimeConsumeTimer(); |
||||||
|
consumeTimer.setEnabled(true); |
||||||
|
consumeTimer.start(); |
||||||
|
Thread.sleep(1100); |
||||||
|
consumeTimer.stop(); |
||||||
|
assertEquals(1, consumeTimer.popTime()); |
||||||
|
assertEquals(0, consumeTimer.popTime()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testMultiTimes() throws InterruptedException { |
||||||
|
TimeConsumeTimer consumeTimer = new TimeConsumeTimer(); |
||||||
|
consumeTimer.setEnabled(true); |
||||||
|
|
||||||
|
consumeTimer.start(); |
||||||
|
Thread.sleep(1010); |
||||||
|
consumeTimer.stop(); |
||||||
|
|
||||||
|
Thread.sleep(2000); |
||||||
|
|
||||||
|
consumeTimer.start(); |
||||||
|
Thread.sleep(1010); |
||||||
|
assertEquals(2, consumeTimer.popTime()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testStartMultiTime() throws InterruptedException { |
||||||
|
TimeConsumeTimer consumeTimer = new TimeConsumeTimer(); |
||||||
|
consumeTimer.setEnabled(true); |
||||||
|
|
||||||
|
consumeTimer.start(); |
||||||
|
Thread.sleep(1010); |
||||||
|
consumeTimer.start(); |
||||||
|
Thread.sleep(1010); |
||||||
|
consumeTimer.start(); |
||||||
|
Thread.sleep(1010); |
||||||
|
|
||||||
|
assertEquals(3, consumeTimer.popTime()); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue