diff --git a/build.third_step0.gradle b/build.third_step0.gradle index 0a76a7a51..a7d30d649 100644 --- a/build.third_step0.gradle +++ b/build.third_step0.gradle @@ -16,7 +16,7 @@ targetCompatibility=1.7 //解压lib下的jar到classes文件夹 -version='10.0' + jar{ baseName="fine-third" zip64 true @@ -42,11 +42,21 @@ FileTree files =fileTree(dir:'./',include:'build*.gradle') def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf (java.io.File.separator)) def branchName=buildDir.substring(buildDir.lastIndexOf (java.io.File.separator)+1) +def date = new Date() +def formattedDate = date.format('yyyy.MM.dd') + def srcDir="." -def MVN_BRANCH = branchVariable.toUpperCase() +def maven_version_build = "" +def indexV = branchName.indexOf( "%2F"); +if(indexV != -1){ + version= branchName.substring(indexV+3, branchName.length()).toUpperCase() + maven_version_build = project.version +"-" + branchName.substring(0, indexV).toUpperCase() +"-SNAPSHOT" +} else { + version= branchName + maven_version_build = project.version +"-SNAPSHOT" +} -// @branch - 分支信息 -def maven_version="${version}-${MVN_BRANCH}-SNAPSHOT" +def maven_version="${version}.${formattedDate}" def jar_version = version configurations { @@ -67,13 +77,32 @@ publishing { groupId "com.fr.third" artifactId "fine-third" version maven_version + ext.repo = 'release' + from components.java + } + + third_build(MavenPublication) { + groupId "com.fr.third" + artifactId "fine-third" + version maven_version_build + ext.repo = 'snapshot' from components.java } } repositories { maven { - - url "http://mvn.finedevelop.com/repository/fanruan/" + name "release" + url "http://mvn.finedevelop.com/repository/fanruan-release/" + credentials { + username = findProperty("NEXUS_USERNAME") + password = findProperty("NEXUS_PASSWORD") + } + + } + + maven { + name "snapshot" + url "http://mvn.finedevelop.com/repository/fanruan/" credentials { username = findProperty("NEXUS_USERNAME") password = findProperty("NEXUS_PASSWORD") @@ -83,6 +112,17 @@ publishing { } } + +afterEvaluate { + tasks.withType(PublishToMavenRepository) { task -> + if (task.publication.hasProperty('repo') && task.publication.repo != task.repository.name) { + task.enabled = false + task.group = null + } + } +} + + task unpack(type:Copy) { delete classesDir destinationDir=file(classesDir) @@ -114,4 +154,3 @@ task unpack(type:Copy) { } jar.dependsOn unpack - diff --git a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/html/simpleparser/HTMLWorker.java b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/html/simpleparser/HTMLWorker.java index b48594a17..11e918722 100644 --- a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/html/simpleparser/HTMLWorker.java +++ b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/html/simpleparser/HTMLWorker.java @@ -775,11 +775,14 @@ public class HTMLWorker implements SimpleXMLDocHandler, DocListener { + " h1 h2 h3 h4 h5 h6 img hr"; public static final HashMap tagsSupported = new HashMap(); + public static final HashMap tagsPrefixSupported = new HashMap(); static { StringTokenizer tok = new StringTokenizer(tagsSupportedString); - while (tok.hasMoreTokens()) - tagsSupported.put(tok.nextToken(), null); + while (tok.hasMoreTokens()) { + String s = tok.nextToken(); + tagsSupported.put(s, null); + tagsPrefixSupported.put(s.charAt(0), null); + } } - } diff --git a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfGraphics2D.java b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfGraphics2D.java index 39f566cb1..b69457ff6 100644 --- a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfGraphics2D.java +++ b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfGraphics2D.java @@ -433,6 +433,7 @@ public class PdfGraphics2D extends Graphics2D { cb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE); if (strokeWidth != 1) { cb.setLineWidth(strokeWidth); + oldStroke = new BasicStroke(strokeWidth); if(realPaint instanceof Color){ Color color = (Color)realPaint; int alpha = color.getAlpha(); diff --git a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/xml/simpleparser/SimpleXMLParser.java b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/xml/simpleparser/SimpleXMLParser.java index 0ef41865b..3bfbcf761 100644 --- a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/xml/simpleparser/SimpleXMLParser.java +++ b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/xml/simpleparser/SimpleXMLParser.java @@ -75,6 +75,7 @@ */ package com.fr.third.com.lowagie.text.xml.simpleparser; +import com.fr.third.com.lowagie.text.html.simpleparser.HTMLWorker; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -117,7 +118,7 @@ public final class SimpleXMLParser { private final static int ATTRIBUTE_KEY = 12; private final static int ATTRIBUTE_EQUAL = 13; private final static int ATTRIBUTE_VALUE = 14; - + /** the state stack */ Stack stack; /** The current character. */ @@ -161,7 +162,7 @@ public final class SimpleXMLParser { String attributekey = null; /** the attribute value. */ String attributevalue = null; - + /** * Creates a Simple XML parser object. * Call go(BufferedReader) immediately after creation. @@ -207,7 +208,7 @@ public final class SimpleXMLParser { } return; } - + // dealing with \n and \r if (character == '\n' && eol) { eol = false; @@ -225,21 +226,18 @@ public final class SimpleXMLParser { } else { columns++; } - + switch(state) { // we are in an unknown state before there's actual content case UNKNOWN: if(character == '<') { - saveState(TEXT); - state = TAG_ENCOUNTERED; + beginnOfTag((char) reader.read(), UNKNOWN); } break; // we can encounter any content case TEXT: if(character == '<') { - flush(); - saveState(state); - state = TAG_ENCOUNTERED; + beginnOfTag((char) reader.read(), TEXT); } else if(character == '&') { saveState(state); entity.setLength(0); @@ -499,6 +497,27 @@ public final class SimpleXMLParser { private void saveState(int s) { stack.push(new Integer(s)); } + + /** + * 处理标签的开头,若不在支持标签范围内,将<符号作为文本处理,例:<1111 (仿造浏览器的处理方式) + */ + public void beginnOfTag(char c, int type) { + previousCharacter = c; + if (c == -1) { + return; + } + if (c == '/' || HTMLWorker.tagsPrefixSupported.containsKey(Character.toLowerCase(c))) { + if (type == TEXT) { + flush(); + } + saveState(TEXT); + state = TAG_ENCOUNTERED; + return; + } + text.append((char) character); + nowhite = true; + } + /** * Flushes the text that is currently in the buffer. * The text can be ignored, added to the document diff --git a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/Markup.java b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/Markup.java index b33b51b9f..85d8a7553 100644 --- a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/Markup.java +++ b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/Markup.java @@ -52,6 +52,8 @@ package com.fr.third.v2.lowagie.text.html; +import com.fr.third.v2.lowagie.text.ElementTags; +import com.fr.third.v2.lowagie.text.html.simpleparser.ChainedProperties; import java.awt.Color; import java.util.ArrayList; import java.util.List; @@ -231,6 +233,9 @@ public class Markup { /** the CSS tag for the horizontal alignment of an object */ public static final String CSS_KEY_TEXTALIGN = "text-align"; + /** the CSS tag for the horizontal alignment of an object */ + public static final String CSS_KEY_ALIGN = "align"; + /** the CSS tag for text decorations */ public static final String CSS_KEY_TEXTDECORATION = "text-decoration"; @@ -430,6 +435,9 @@ public class Markup { if (string.startsWith("em")) { return f * actualFontSize; } + if (string.startsWith("%")) { + return f * actualFontSize / 100; + } // one ex is the x-height of a font (x-height is usually about half the // font-size) if (string.startsWith("ex")) { @@ -439,6 +447,21 @@ public class Markup { return f; } + /** + * 解析当前字号(可能是继承来的) + * + * @param cprops + * @return + */ + public static float parseDefaultFontSize(ChainedProperties cprops) { + if (null == cprops) { + return DEFAULT_FONT_SIZE; + } + String size = cprops.getProperty(ElementTags.SIZE); + return null == size ? Markup.DEFAULT_FONT_SIZE : Markup.parseLength(size, + Markup.DEFAULT_FONT_SIZE); + } + /** * Converts a Color into a HTML representation of this * Color. diff --git a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/ChainedProperties.java b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/ChainedProperties.java index 870741bf5..c0a7d6ae0 100644 --- a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/ChainedProperties.java +++ b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/ChainedProperties.java @@ -76,11 +76,11 @@ public class ChainedProperties { return null; } - public String getLastChainProperty(String key){ + public String getLastChainProperty(String key) { if (0 == chain.size()) { return null; } - Object obj[] = (Object[]) chain.get(chain.size()-1); + Object obj[] = (Object[]) chain.get(chain.size() - 1); HashMap prop = (HashMap) obj[1]; return (String) prop.get(key); } @@ -217,4 +217,31 @@ public class ChainedProperties { return null; } + /** + * 获取当前处理的标签 + * + * @return 标签名 + */ + public String getLastTag() { + if (chain.size() == 0) { + return null; + } + Object obj[] = (Object[]) chain.get(chain.size() - 1); + return (String) obj[0]; + } + + /** + * 判断 LastChain 是否存在一对 Key - value + * + * @param key + * @param value + * @return + */ + public boolean hasKvInLastChain(String key, String value) { + String actualValue = getLastChainProperty(key); + if (null == actualValue && null == value) { + return true; + } + return null == value ? actualValue.equals(value) : value.equals(actualValue); + } } diff --git a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/FactoryProperties.java b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/FactoryProperties.java index 50f7c1716..db5f11f90 100644 --- a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/FactoryProperties.java +++ b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/FactoryProperties.java @@ -50,6 +50,7 @@ package com.fr.third.v2.lowagie.text.html.simpleparser; +import com.fr.third.v2.lowagie.text.html.CSS; import com.fr.third.v2.lowagie.text.html.BorderAttribute; import com.fr.third.v2.lowagie.text.html.utils.BackgroundUtil; import com.fr.third.v2.lowagie.text.html.utils.BorderUtils; @@ -57,6 +58,7 @@ import java.awt.Color; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.List; import java.util.Properties; import java.util.StringTokenizer; import com.fr.third.v2.lowagie.text.Chunk; @@ -107,6 +109,7 @@ public class FactoryProperties { } return ck; } + private static void setParagraphLeading(Paragraph p, String leading) { if (leading == null) { p.setLeading(0, 1.5f); @@ -150,18 +153,10 @@ public class FactoryProperties { if (props.hasProperty("noexist-attrid")) { p.setAttribute("noexist-attrid", props.getProperty("noexist-attrid")); } - for(String margin : HtmlConstants.MARGIN){ - if(props.hasPropertyInChain("div", margin)){ - String ss = props.getPropertyFromChain("div", margin); - p.setAttribute(margin, ss); - } - } - for(String padding : HtmlConstants.PADDING){ - if(props.hasPropertyInChain("div", padding)){ - String ss = props.getPropertyFromChain("div", padding); - p.setAttribute(padding, ss); - } - } + + parseAlignAttr(p, props); + parseMarginAttr(p, props); + parsePaddingAttr(p, props); String lastBlockTag = props.getLastBlockTag(); //这里解析的背景属性不能是table标签的 @@ -179,7 +174,7 @@ public class FactoryProperties { p.setHyphenation(getHyphenation(props)); setParagraphLeading(p, props.getProperty("leading")); - value = props.getProperty("before"); + String value = props.getProperty("before"); if (value != null) { try { p.setSpacingBefore(Float.parseFloat(value)); @@ -202,6 +197,76 @@ public class FactoryProperties { } } + /** + * 解析align属性 + * + * @param p + * @param props + */ + private static void parseAlignAttr(Paragraph p, ChainedProperties props) { + String[] keys = new String[]{Markup.CSS_KEY_ALIGN, Markup.CSS_KEY_TEXTALIGN}; + for (String key : keys) { + String value = props.getPropertyFromChain("div", key); + if (null == value) { + continue; + } + if (value.equalsIgnoreCase("center")) + p.setAlignment(Element.ALIGN_CENTER); + else if (value.equalsIgnoreCase("right")) + p.setAlignment(Element.ALIGN_RIGHT); + else if (value.equalsIgnoreCase("left")) + p.setAlignment(Element.ALIGN_LEFT); + else if (value.equalsIgnoreCase("justify")) + p.setAlignment(Element.ALIGN_JUSTIFIED); + } + } + + /** + * 解析margin属性 + * + * @param p + * @param props + */ + private static void parseMarginAttr(Paragraph p, ChainedProperties props) { + if (props.hasPropertyInChain("div", Markup.CSS_KEY_MARGIN)) { + List list = Markup.parseNESW(props.getPropertyFromChain("div", Markup.CSS_KEY_MARGIN)); + if (null != list && 4 == list.size()) { + for (int i = 0; i < HtmlConstants.MARGIN.size() && i < list.size(); i++) { + p.setAttribute(HtmlConstants.MARGIN.get(i), String.valueOf(Markup.parseLength(list.get(i), Markup.parseDefaultFontSize(props)))); + } + } + } + for (String margin : HtmlConstants.MARGIN) { + if (props.hasPropertyInChain("div", margin)) { + String ss = props.getPropertyFromChain("div", margin); + p.setAttribute(margin, String.valueOf(Markup.parseLength(ss, Markup.parseDefaultFontSize(props)))); + } + } + } + + /** + * 解析padding属性 + * + * @param p + * @param props + */ + private static void parsePaddingAttr(Paragraph p, ChainedProperties props) { + if (props.hasPropertyInChain("div", Markup.CSS_KEY_PADDING)) { + List list = Markup.parseNESW(props.getPropertyFromChain("div", Markup.CSS_KEY_PADDING)); + if (null != list && 4 == list.size()) { + for (int i = 0; i < HtmlConstants.PADDING.size() && i < list.size(); i++) { + p.setAttribute(HtmlConstants.PADDING.get(i), list.get(i)); + } + } + } + for (String padding : HtmlConstants.PADDING) { + if (props.hasPropertyInChain("div", padding)) { + String ss = props.getPropertyFromChain("div", padding); + p.setAttribute(padding, ss); + } + } + } + public static Paragraph createParagraph(ChainedProperties props) { Paragraph p = new Paragraph(); createParagraph(p, props); @@ -392,17 +457,32 @@ public class FactoryProperties { dealWithFontSizeOrTextIndent(h, cprops, prop, key); } else if (key.equals(Markup.CSS_KEY_FONTSTYLE)) { String ss = prop.getProperty(key).trim().toLowerCase(); - if (ss.equals("italic") || ss.equals("oblique")) + if (ss.equals("italic") || ss.equals("oblique")) { h.put("i", null); + } else { + h.remove("i"); + } } else if (key.equals(Markup.CSS_KEY_FONTWEIGHT)) { String ss = prop.getProperty(key).trim().toLowerCase(); if (ss.equals("bold") || ss.equals("700") || ss.equals("800") - || ss.equals("900")) + || ss.equals("900")){ h.put("b", null); + }else { + h.remove("b"); + } } else if (key.equals(Markup.CSS_KEY_TEXTDECORATION)) { String ss = prop.getProperty(key).trim().toLowerCase(); - if (ss.equals(Markup.CSS_VALUE_UNDERLINE)) + if (ss.equals(Markup.CSS_VALUE_UNDERLINE)) { + h.remove("s"); h.put("u", null); + } else if (ss.equals(Markup.CSS_VALUE_LINETHROUGH)) { + h.remove("u"); + h.put("s", null); + } else { + h.remove("u"); + h.remove("s"); + h.put(key, ss); + } } else if (key.equals(Markup.CSS_KEY_COLOR)) { Color c = Markup.decodeColor(prop.getProperty(key)); if (c != null) { @@ -484,5 +564,6 @@ public class FactoryProperties { followTags.put("strong", "b"); followTags.put("s", "s"); followTags.put("strike", "s"); + followTags.put("del", "s"); } } diff --git a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/HTMLWorker.java b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/HTMLWorker.java index a3558dab3..c16dd77f8 100644 --- a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/HTMLWorker.java +++ b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/HTMLWorker.java @@ -50,6 +50,7 @@ package com.fr.third.v2.lowagie.text.html.simpleparser; +import com.fr.third.v2.lowagie.text.html.utils.DefaultPropertiesHandleUtils; import com.fr.third.v2.lowagie.text.pdf.PdfFont; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; @@ -211,16 +212,13 @@ public class HTMLWorker implements SimpleXMLDocHandler, DocListener { return; try { style.applyStyle(tag, h); - if(tag.equals("p")){ - h.put(Markup.CSS_KEY_MARGINTOP, "16px"); - h.put(Markup.CSS_KEY_MARGINBOTTOM, "16px"); - } + DefaultPropertiesHandleUtils.fillDefaultProperties(tag, h); String follow = (String) FactoryProperties.followTags.get(tag); if (follow != null) { HashMap prop = new HashMap(); prop.put(follow, null); - FactoryProperties.insertStyle(h, this.cprops); prop.putAll(h); + FactoryProperties.insertStyle(prop, this.cprops); cprops.addToChain(follow, prop); return; } @@ -228,7 +226,8 @@ public class HTMLWorker implements SimpleXMLDocHandler, DocListener { if (tag.equals(HtmlTags.ANCHOR)) { cprops.addToChain(tag, h); if (currentParagraph == null) { - currentParagraph = new Paragraph(); + currentParagraph = FactoryProperties + .createParagraph(cprops); } stack.push(currentParagraph); currentParagraph = new Paragraph(); @@ -236,7 +235,8 @@ public class HTMLWorker implements SimpleXMLDocHandler, DocListener { } if (tag.equals(HtmlTags.NEWLINE)) { if (currentParagraph == null) { - currentParagraph = new Paragraph(); + currentParagraph = FactoryProperties + .createParagraph(cprops); } currentParagraph.add(factoryProperties .createChunk("\n", cprops)); @@ -727,7 +727,8 @@ public class HTMLWorker implements SimpleXMLDocHandler, DocListener { currentParagraph.add(chunk); return; } - if (content.trim().length() == 0 && content.indexOf(' ') < 0) { + + if (content.trim().length() == 0 && null == currentParagraph) { return; } @@ -821,7 +822,7 @@ public class HTMLWorker implements SimpleXMLDocHandler, DocListener { return true; } - public static final String tagsSupportedString = "ol ul li a pre font span br p div body table td th tr i b u sub sup em strong s strike" + public static final String tagsSupportedString = "ol ul li a pre font span br p div body table td th tr i b u sub sup em strong s strike del" + " h1 h2 h3 h4 h5 h6 img hr"; public static final HashMap tagsSupported = new HashMap(); diff --git a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/HtmlConstants.java b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/HtmlConstants.java index 46757a8a9..97949db6e 100644 --- a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/HtmlConstants.java +++ b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/HtmlConstants.java @@ -45,15 +45,16 @@ public class HtmlConstants { INLINE_ELEMENTS.add(HtmlTags.I); INLINE_ELEMENTS.add(HtmlTags.U); INLINE_ELEMENTS.add(HtmlTags.EM); - PADDING.add(Markup.CSS_KEY_PADDINGLEFT); - PADDING.add(Markup.CSS_KEY_PADDINGRIGHT); + PADDING.add(Markup.CSS_KEY_PADDINGTOP); + PADDING.add(Markup.CSS_KEY_PADDINGRIGHT); PADDING.add(Markup.CSS_KEY_PADDINGBOTTOM); - MARGIN.add(Markup.CSS_KEY_MARGINLEFT); - MARGIN.add(Markup.CSS_KEY_MARGINRIGHT); + PADDING.add(Markup.CSS_KEY_PADDINGLEFT); + MARGIN.add(Markup.CSS_KEY_MARGINTOP); + MARGIN.add(Markup.CSS_KEY_MARGINRIGHT); MARGIN.add(Markup.CSS_KEY_MARGINBOTTOM); - + MARGIN.add(Markup.CSS_KEY_MARGINLEFT); //按照上 右 下 左 的顺序排 BORDER.add(Markup.CSS_KEY_BORDERTOP); @@ -75,5 +76,6 @@ public class HtmlConstants { BORDER_COLOR.add(Markup.CSS_KEY_BORDERCOLORRIGHT); BORDER_COLOR.add(Markup.CSS_KEY_BORDERCOLORBOTTOM); BORDER_COLOR.add(Markup.CSS_KEY_BORDERCOLORLEFT); + } } diff --git a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/IncCell.java b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/IncCell.java index 8c8a8c2a3..6b2af0674 100644 --- a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/IncCell.java +++ b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/simpleparser/IncCell.java @@ -70,12 +70,13 @@ public class IncCell implements TextElementArray { */ public IncCell(String tag, ChainedProperties props) { cell = new PdfPCell((Phrase) null); + cell.setHorizontalAlignment(Element.ALIGN_UNDEFINED); String value = props.getProperty("colspan"); if (value != null) cell.setColspan(Integer.parseInt(value)); value = props.getProperty("align"); - if (tag.equals("th")) - cell.setHorizontalAlignment(Element.ALIGN_CENTER); +// if (tag.equals("th")) +// cell.setHorizontalAlignment(Element.ALIGN_CENTER); if (value != null) { if ("center".equalsIgnoreCase(value)) cell.setHorizontalAlignment(Element.ALIGN_CENTER); diff --git a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/utils/DefaultPropertiesHandleUtils.java b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/utils/DefaultPropertiesHandleUtils.java new file mode 100644 index 000000000..58a9043f6 --- /dev/null +++ b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/html/utils/DefaultPropertiesHandleUtils.java @@ -0,0 +1,90 @@ +package com.fr.third.v2.lowagie.text.html.utils; + +import com.fr.third.v2.lowagie.text.html.HtmlTags; +import com.fr.third.v2.lowagie.text.html.Markup; +import java.util.HashMap; +import java.util.Properties; + +/** + * 处理标签默认属性值 + * + * @author Hugh.C + * @version 1.0 + * Created by Hugh.C on 2020/7/3 + */ +public class DefaultPropertiesHandleUtils { + + //h1-h6 标签默认字体大小 + private static final HashMap H_TAG_DEFAULT_FONT_SIZE = new HashMap(6); + + //h1-h6 标签默认margin-top and bottom大小 + private static final HashMap H_TAG_DEFAULT_MARGIN = new HashMap(6); + + + static { + H_TAG_DEFAULT_FONT_SIZE.put("h1", "2em"); + H_TAG_DEFAULT_FONT_SIZE.put("h2", "1.5em"); + H_TAG_DEFAULT_FONT_SIZE.put("h3", "1.17em"); + H_TAG_DEFAULT_FONT_SIZE.put("h4", "1em"); + H_TAG_DEFAULT_FONT_SIZE.put("h5", "0.83em"); + H_TAG_DEFAULT_FONT_SIZE.put("h6", "0.67em"); + + H_TAG_DEFAULT_MARGIN.put("h1", "0.67em"); + H_TAG_DEFAULT_MARGIN.put("h2", "0.83em"); + H_TAG_DEFAULT_MARGIN.put("h3", "1em"); + H_TAG_DEFAULT_MARGIN.put("h4", "1.33em"); + H_TAG_DEFAULT_MARGIN.put("h5", "1.67em"); + H_TAG_DEFAULT_MARGIN.put("h6", "2.33em"); + } + + /** + * 填充默认属性值 + * + * @param tag + * @param h + */ + public static void fillDefaultProperties(String tag, HashMap h) { + if (null == tag || null == h) { + return; + } + if (HtmlTags.HEADERCELL.endsWith(tag)) { + h.put("b", null); + return; + } + if (HtmlTags.ANCHOR.equals(tag)) { + h.put("u", null); + h.put("color", "blue"); + return; + } + + String style = (String) h.get("style"); + if (HtmlTags.PARAGRAPH.equals(tag)) { + Properties props = Markup.parseAttributes(style); + if (!props.containsKey(Markup.CSS_KEY_MARGINTOP)) { + h.put(Markup.CSS_KEY_MARGINTOP, "1em"); + } + if (!props.containsKey(Markup.CSS_KEY_MARGINBOTTOM)) { + h.put(Markup.CSS_KEY_MARGINBOTTOM, "1em"); + } + return; + } + + if (H_TAG_DEFAULT_FONT_SIZE.containsKey(tag)) { + h.put("b", null); + Properties props = Markup.parseAttributes(style); + if (!props.containsKey(Markup.CSS_KEY_MARGINTOP)) { + h.put(Markup.CSS_KEY_MARGINTOP, H_TAG_DEFAULT_MARGIN.get(tag)); + } + if (!props.containsKey(Markup.CSS_KEY_MARGINBOTTOM)) { + h.put(Markup.CSS_KEY_MARGINBOTTOM, H_TAG_DEFAULT_MARGIN.get(tag)); + } + if (!props.containsKey(Markup.CSS_KEY_FONTSIZE)) { + h.put("style", new StringBuilder(null == style ? "" : style).append(";") + .append(Markup.CSS_KEY_FONTSIZE).append(":").append(H_TAG_DEFAULT_FONT_SIZE.get(tag)).append(";").toString()); + } + return; + } + + } + +} diff --git a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java index 44a02083e..78c76d50d 100644 --- a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java +++ b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java @@ -832,6 +832,21 @@ public class PdfChunk { public String toHtmlString() { StringBuffer htmlString = new StringBuffer(); + String hyperlink =getHyperlink(); + if (null != hyperlink && hyperlink.length() > 0) { + htmlString.append(""); + if (this.isImage()) { + htmlString.append(""); + } else { + htmlString.append(value); + } + htmlString.append(""); + return htmlString.toString(); + } if (this.isImage()) { htmlString.append(" classForName(String className) throws ClassNotFoundException; Class classForName(String className, ClassLoader classLoader) throws ClassNotFoundException; -} \ No newline at end of file +} diff --git a/fine-jackson/src/main/java/com/fr/third/fasterxml/jackson/databind/type/TypeFactory.java b/fine-jackson/src/main/java/com/fr/third/fasterxml/jackson/databind/type/TypeFactory.java index 9d9455cb6..efa990886 100644 --- a/fine-jackson/src/main/java/com/fr/third/fasterxml/jackson/databind/type/TypeFactory.java +++ b/fine-jackson/src/main/java/com/fr/third/fasterxml/jackson/databind/type/TypeFactory.java @@ -137,7 +137,7 @@ public final class TypeFactory * ClassLoader used by this factory [databind#624]. */ protected final ClassLoader _classLoader; - + private ClassFactory classFactory; /* @@ -146,6 +146,7 @@ public final class TypeFactory /********************************************************** */ + public void setClassFactory(ClassFactory classFactory) { this.classFactory = classFactory; diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/Scheduler.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/Scheduler.java index 88cc7bd45..ccff10414 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/Scheduler.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/Scheduler.java @@ -198,6 +198,13 @@ public interface Scheduler { * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + /** + * 切换指定节点id + * @param oldId 旧id + * @param newId 新id + */ + void changeAppointId(String oldId, String newId); + /** * Returns the name of the Scheduler. */ diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/Trigger.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/Trigger.java index b64ed0bc4..7d630c118 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/Trigger.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/Trigger.java @@ -127,6 +127,10 @@ public interface Trigger extends Serializable, Cloneable, Comparable { */ public static final int DEFAULT_PRIORITY = 5; + String getAppointId(); + + void setAppointId(String appointId); + public TriggerKey getKey(); public JobKey getJobKey(); diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/TriggerBuilder.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/TriggerBuilder.java index db8ed1e7c..88de74055 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/TriggerBuilder.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/TriggerBuilder.java @@ -71,6 +71,7 @@ public class TriggerBuilder { private String calendarName; private JobKey jobKey; private JobDataMap jobDataMap = new JobDataMap(); + private String appointId; private ScheduleBuilder scheduleBuilder = null; @@ -99,7 +100,8 @@ public class TriggerBuilder { if(scheduleBuilder == null) scheduleBuilder = SimpleScheduleBuilder.simpleSchedule(); MutableTrigger trig = scheduleBuilder.build(); - + + trig.setAppointId(appointId); trig.setCalendarName(calendarName); trig.setDescription(description); trig.setStartTime(startTime); @@ -117,6 +119,11 @@ public class TriggerBuilder { return (T) trig; } + public TriggerBuilder appointId(String appointId) { + this.appointId = appointId; + return this; + } + /** * Use a TriggerKey with the given name and default group to * identify the Trigger. diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/core/QuartzScheduler.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/core/QuartzScheduler.java index 7914ef664..048c2d709 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/core/QuartzScheduler.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/core/QuartzScheduler.java @@ -860,6 +860,10 @@ public class QuartzScheduler implements RemotableQuartzScheduler { return ft; } + public void changeAppointId(String oldId, String newId) { + resources.getJobStore().changeAppointId(oldId, newId); + } + /** *

* Schedule the given {@link Trigger} with the diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/RemoteMBeanScheduler.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/RemoteMBeanScheduler.java index 01910855e..1f615f644 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/RemoteMBeanScheduler.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/RemoteMBeanScheduler.java @@ -165,6 +165,11 @@ public abstract class RemoteMBeanScheduler implements Scheduler { * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + @Override + public void changeAppointId(String oldId, String newId) { + // do nothing + } + /** *

* Returns the name of the Scheduler. diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/RemoteScheduler.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/RemoteScheduler.java index f8272b565..a803e085a 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/RemoteScheduler.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/RemoteScheduler.java @@ -131,6 +131,11 @@ public class RemoteScheduler implements Scheduler { return ex; } + @Override + public void changeAppointId(String oldId, String newId) { + // do nothing + } + /** *

* Returns the name of the Scheduler. diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/StdScheduler.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/StdScheduler.java index e8ae613d4..0dc100946 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/StdScheduler.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/StdScheduler.java @@ -89,6 +89,11 @@ public class StdScheduler implements Scheduler { * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + @Override + public void changeAppointId(String oldId, String newId) { + sched.changeAppointId(oldId, newId); + } + /** *

* Returns the name of the Scheduler. diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/StdSchedulerFactory.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/StdSchedulerFactory.java index 9e3b1f626..062ed8867 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/StdSchedulerFactory.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/StdSchedulerFactory.java @@ -193,6 +193,8 @@ public class StdSchedulerFactory implements SchedulerFactory { public static final String PROP_JOB_STORE_PREFIX = "com.fr.third.v2.org.quartz.jobStore"; + public static final String PROP_JOB_STORE_CURRENT_ID = "com.fr.third.v2.org.quartz.jobStore.currentId"; + public static final String PROP_JOB_STORE_LOCK_HANDLER_PREFIX = PROP_JOB_STORE_PREFIX + ".lockHandler"; public static final String PROP_JOB_STORE_LOCK_HANDLER_CLASS = PROP_JOB_STORE_LOCK_HANDLER_PREFIX + ".class"; @@ -860,8 +862,11 @@ public class StdSchedulerFactory implements SchedulerFactory { throw initException; } + String currentId = cfg.getStringProperty(PROP_JOB_STORE_CURRENT_ID); + try { js = (JobStore) loadHelper.loadClass(jsClass).newInstance(); + js.setCurrentId(currentId); } catch (Exception e) { initException = new SchedulerException("JobStore class '" + jsClass + "' could not be instantiated.", e); diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/Constants.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/Constants.java index 60290765c..252600ce7 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/Constants.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/Constants.java @@ -105,6 +105,8 @@ public interface Constants { String ALIAS_COL_NEXT_FIRE_TIME = "ALIAS_NXT_FR_TM"; + String COL_APPOINT_ID= "APPOINT_ID"; + // TABLE_SIMPLE_TRIGGERS columns names String COL_REPEAT_COUNT = "REPEAT_COUNT"; diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/DriverDelegate.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/DriverDelegate.java index f95dbfb89..d449b2428 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/DriverDelegate.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/DriverDelegate.java @@ -99,6 +99,10 @@ public interface DriverDelegate { String newState, String oldState1, String oldState2) throws SQLException; + int updateTriggerStatesFromOtherStates(Connection conn, String newState, String oldState1, String oldState2, String oldState3) throws SQLException; + + int updateTriggerAppointId(Connection conn, String oldId, String newId) throws SQLException; + /** *

* Get the names of all of the triggers that have misfired - according to @@ -968,6 +972,8 @@ public interface DriverDelegate { public List selectTriggerToAcquire(Connection conn, long noLaterThan, long noEarlierThan, int maxCount) throws SQLException; + List selectAppointTriggerToAcquire(Connection conn, long noLaterThan, long noEarlierThan, int maxCount, String appointId); + /** *

* Insert a fired trigger. diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/JobStoreSupport.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/JobStoreSupport.java index 4f3a3d6b0..a6e451966 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/JobStoreSupport.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/JobStoreSupport.java @@ -159,6 +159,8 @@ public abstract class JobStoreSupport implements JobStore, Constants { private volatile boolean schedulerRunning = false; private volatile boolean shutdown = false; + private volatile String currentId; + /* * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @@ -167,6 +169,32 @@ public abstract class JobStoreSupport implements JobStore, Constants { * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + @Override + public void setCurrentId(String currentId) { + this.currentId = currentId; + } + + @Override + public void changeAppointId(final String oldId, final String newId) { + + try { + executeInNonManagedTXLock( + LOCK_TRIGGER_ACCESS, + new VoidTransactionCallback() { + public void executeVoid(Connection conn) throws JobPersistenceException { + try { + int rows = getDelegate().updateTriggerAppointId(conn, oldId, newId); + getLog().info("update " + rows + " triggers appointId from " + oldId + " to " + newId); + } catch (SQLException e) { + throw new JobPersistenceException("Couldn't update appointId: " + e.getMessage(), e); + } + } + }, null); + } catch (JobPersistenceException e) { + getLog().error(e.getMessage()); + } + } + /** *

* Set the name of the DataSource that should be used for @@ -854,14 +882,14 @@ public abstract class JobStoreSupport implements JobStore, Constants { try { // update inconsistent job states int rows = getDelegate().updateTriggerStatesFromOtherStates(conn, - STATE_WAITING, STATE_ACQUIRED, STATE_BLOCKED); + STATE_WAITING, STATE_ACQUIRED, STATE_BLOCKED, STATE_ERROR); rows += getDelegate().updateTriggerStatesFromOtherStates(conn, STATE_PAUSED, STATE_PAUSED_BLOCKED, STATE_PAUSED_BLOCKED); getLog().info( "Freed " + rows - + " triggers from 'acquired' / 'blocked' state."); + + " triggers from 'acquired' / 'blocked' / 'error' state."); // clean up misfired jobs recoverMisfiredJobs(conn, true); @@ -2780,6 +2808,17 @@ public abstract class JobStoreSupport implements JobStore, Constants { }); } + private void mergeKeys(List allKeys, Set allKeyIds, List mergeKeys) { + if (mergeKeys != null) { + for (TriggerKey key : mergeKeys) { + if (!allKeyIds.contains(key.toString())) { + allKeys.add(key); + allKeyIds.add(key.toString()); + } + } + } + } + // FUTURE_TODO: this really ought to return something like a FiredTriggerBundle, // so that the fireInstanceId doesn't have to be on the trigger... protected List acquireNextTrigger(Connection conn, long noLaterThan, int maxCount, long timeWindow) @@ -2795,15 +2834,22 @@ public abstract class JobStoreSupport implements JobStore, Constants { do { currentLoopCount++; try { - List keys = getDelegate().selectTriggerToAcquire(conn, noLaterThan + timeWindow, getMisfireTime(), maxCount); + long misfireTime = getMisfireTime(); + List waitingKeys = getDelegate().selectTriggerToAcquire(conn, noLaterThan + timeWindow, misfireTime, maxCount); + List appointKeys = getDelegate().selectAppointTriggerToAcquire(conn, noLaterThan + timeWindow, misfireTime, maxCount, this.currentId); + List allKeys = new ArrayList(); + Set keyIds = new HashSet(); + + mergeKeys(allKeys, keyIds, waitingKeys); + mergeKeys(allKeys, keyIds, appointKeys); // No trigger is ready to fire yet. - if (keys == null || keys.size() == 0) + if (keyIds.size() == 0) return acquiredTriggers; long batchEnd = noLaterThan; - for (TriggerKey triggerKey : keys) { + for (TriggerKey triggerKey : allKeys) { // If our trigger is no longer available, try a new one. OperableTrigger nextTrigger = retrieveTrigger(conn, triggerKey); if (nextTrigger == null) { diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/PointbaseDelegate.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/PointbaseDelegate.java index 5cf9398a0..01bc08c93 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/PointbaseDelegate.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/PointbaseDelegate.java @@ -181,6 +181,7 @@ public class PointbaseDelegate extends StdJDBCDelegate { ps.setInt(13, trigger.getMisfireInstruction()); ps.setBinaryStream(14, bais, len); ps.setInt(15, trigger.getPriority()); + ps.setString(16, trigger.getAppointId()); insertResult = ps.executeUpdate(); diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/StdJDBCConstants.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/StdJDBCConstants.java index 6a20af625..56c85c477 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/StdJDBCConstants.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/StdJDBCConstants.java @@ -47,19 +47,44 @@ public interface StdJDBCConstants extends Constants { String SCHED_NAME_SUBST = "{1}"; // QUERIES - String UPDATE_TRIGGER_STATES_FROM_OTHER_STATES = "UPDATE " + String UPDATE_TRIGGER_STATES_FROM_OTHER_2_STATES = "UPDATE " + TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " SET " + COL_TRIGGER_STATE + " = ?" + " WHERE " - + COL_SCHEDULER_NAME + + COL_SCHEDULER_NAME + " = " + SCHED_NAME_SUBST + " AND (" + COL_TRIGGER_STATE + " = ? OR " + COL_TRIGGER_STATE + " = ?)"; + String UPDATE_TRIGGER_STATES_FROM_OTHER_3_STATES = "UPDATE " + + TABLE_PREFIX_SUBST + + TABLE_TRIGGERS + + " SET " + + COL_TRIGGER_STATE + + " = ?" + + " WHERE " + + COL_SCHEDULER_NAME + + " = " + SCHED_NAME_SUBST + " AND (" + + COL_TRIGGER_STATE + + " = ? OR " + + COL_TRIGGER_STATE + + " = ? OR " + + COL_TRIGGER_STATE + " = ?)"; + + String UPDATE_TRIGGER_APPOINT_ID = "UPDATE " + + TABLE_PREFIX_SUBST + + TABLE_TRIGGERS + + " SET " + + COL_APPOINT_ID + + " = ?" + + " WHERE " + + COL_APPOINT_ID + + " = ?"; + String SELECT_MISFIRED_TRIGGERS = "SELECT * FROM " + TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " WHERE " + COL_SCHEDULER_NAME + " = " + SCHED_NAME_SUBST @@ -212,8 +237,8 @@ public interface StdJDBCConstants extends Constants { + ", " + COL_NEXT_FIRE_TIME + ", " + COL_PREV_FIRE_TIME + ", " + COL_TRIGGER_STATE + ", " + COL_TRIGGER_TYPE + ", " + COL_START_TIME + ", " + COL_END_TIME + ", " + COL_CALENDAR_NAME - + ", " + COL_MISFIRE_INSTRUCTION + ", " + COL_JOB_DATAMAP + ", " + COL_PRIORITY + ") " - + " VALUES(" + SCHED_NAME_SUBST + ", ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + ", " + COL_MISFIRE_INSTRUCTION + ", " + COL_JOB_DATAMAP + ", " + COL_PRIORITY + ", " + COL_APPOINT_ID + ") " + + " VALUES(" + SCHED_NAME_SUBST + ", ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; String INSERT_SIMPLE_TRIGGER = "INSERT INTO " + TABLE_PREFIX_SUBST + TABLE_SIMPLE_TRIGGERS + " (" @@ -507,13 +532,24 @@ public interface StdJDBCConstants extends Constants { + " AND " + COL_TRIGGER_STATE + " = ? AND " + COL_NEXT_FIRE_TIME + " = ?"; String SELECT_NEXT_TRIGGER_TO_ACQUIRE = "SELECT " - + COL_TRIGGER_NAME + ", " + COL_TRIGGER_GROUP + ", " - + COL_NEXT_FIRE_TIME + ", " + COL_PRIORITY + " FROM " - + TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " WHERE " - + COL_SCHEDULER_NAME + " = " + SCHED_NAME_SUBST - + " AND " + COL_TRIGGER_STATE + " = ? AND " + COL_NEXT_FIRE_TIME + " <= ? " - + "AND (" + COL_MISFIRE_INSTRUCTION + " = -1 OR (" +COL_MISFIRE_INSTRUCTION+ " != -1 AND "+ COL_NEXT_FIRE_TIME + " >= ?)) " - + "ORDER BY "+ COL_NEXT_FIRE_TIME + " ASC, " + COL_PRIORITY + " DESC"; + + COL_TRIGGER_NAME + ", " + COL_TRIGGER_GROUP + ", " + + COL_NEXT_FIRE_TIME + ", " + COL_PRIORITY + " FROM " + + TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " WHERE " + + COL_SCHEDULER_NAME + " = " + SCHED_NAME_SUBST + + " AND " + COL_APPOINT_ID + " IS NULL" + + " AND " + COL_TRIGGER_STATE + " = ? AND " + COL_NEXT_FIRE_TIME + " <= ? " + + "AND (" + COL_MISFIRE_INSTRUCTION + " = -1 OR (" + COL_MISFIRE_INSTRUCTION + " != -1 AND " + COL_NEXT_FIRE_TIME + " >= ?)) " + + "ORDER BY " + COL_NEXT_FIRE_TIME + " ASC, " + COL_PRIORITY + " DESC"; + + String SELECT_NEXT_APPOINT_TRIGGER_TO_ACQUIRE = "SELECT " + + COL_TRIGGER_NAME + ", " + COL_TRIGGER_GROUP + ", " + + COL_NEXT_FIRE_TIME + ", " + COL_PRIORITY + " FROM " + + TABLE_PREFIX_SUBST + TABLE_TRIGGERS + " WHERE " + + COL_SCHEDULER_NAME + " = " + SCHED_NAME_SUBST + + " AND " + COL_APPOINT_ID + " = ?" + + " AND " + COL_TRIGGER_STATE + " = ? AND " + COL_NEXT_FIRE_TIME + " <= ? " + + "AND (" + COL_MISFIRE_INSTRUCTION + " = -1 OR (" + COL_MISFIRE_INSTRUCTION + " != -1 AND " + COL_NEXT_FIRE_TIME + " >= ?)) " + + "ORDER BY " + COL_NEXT_FIRE_TIME + " ASC, " + COL_PRIORITY + " DESC"; String INSERT_FIRED_TRIGGER = "INSERT INTO " diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/StdJDBCDelegate.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/StdJDBCDelegate.java index add26e57b..73fc912ad 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/StdJDBCDelegate.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/StdJDBCDelegate.java @@ -227,8 +227,7 @@ public class StdJDBCDelegate implements DriverDelegate, StdJDBCConstants { PreparedStatement ps = null; try { - ps = conn - .prepareStatement(rtp(UPDATE_TRIGGER_STATES_FROM_OTHER_STATES)); + ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_STATES_FROM_OTHER_2_STATES)); ps.setString(1, newState); ps.setString(2, oldState1); ps.setString(3, oldState2); @@ -238,6 +237,38 @@ public class StdJDBCDelegate implements DriverDelegate, StdJDBCConstants { } } + @Override + public int updateTriggerStatesFromOtherStates(Connection conn, String newState, String oldState1, String oldState2, String oldState3) throws SQLException { + + PreparedStatement ps = null; + try { + ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_STATES_FROM_OTHER_3_STATES)); + ps.setString(1, newState); + ps.setString(2, oldState1); + ps.setString(3, oldState2); + ps.setString(4, oldState3); + + return ps.executeUpdate(); + } finally { + closeStatement(ps); + } + } + + @Override + public int updateTriggerAppointId(Connection conn, String oldId, String newId) throws SQLException { + + PreparedStatement ps = null; + try { + ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_APPOINT_ID)); + ps.setString(1, newId); + ps.setString(2, oldId); + + return ps.executeUpdate(); + } finally { + closeStatement(ps); + } + } + /** *

* Get the names of all of the triggers that have misfired. @@ -1088,6 +1119,7 @@ public class StdJDBCDelegate implements DriverDelegate, StdJDBCConstants { ps.setInt(13, trigger.getMisfireInstruction()); setBytes(ps, 14, baos); ps.setInt(15, trigger.getPriority()); + ps.setString(16, trigger.getAppointId()); insertResult = ps.executeUpdate(); @@ -2624,6 +2656,40 @@ public class StdJDBCDelegate implements DriverDelegate, StdJDBCConstants { } } + public List selectAppointTriggerToAcquire(Connection conn, long noLaterThan, long noEarlierThan, int maxCount, String appointId) { + PreparedStatement ps = null; + ResultSet rs = null; + List nextTriggers = new LinkedList(); + try { + ps = conn.prepareStatement(rtp(SELECT_NEXT_APPOINT_TRIGGER_TO_ACQUIRE)); + if (maxCount < 1) + maxCount = 1; + + ps.setMaxRows(maxCount); + ps.setFetchSize(maxCount); + + ps.setString(1, appointId); + ps.setString(2, STATE_WAITING); + ps.setBigDecimal(3, new BigDecimal(String.valueOf(noLaterThan))); + ps.setBigDecimal(4, new BigDecimal(String.valueOf(noEarlierThan))); + rs = ps.executeQuery(); + + while (rs.next() && nextTriggers.size() <= maxCount) { + nextTriggers.add(TriggerKey.triggerKey( + rs.getString(COL_TRIGGER_NAME), + rs.getString(COL_TRIGGER_GROUP))); + } + + return nextTriggers; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } finally { + closeResultSet(rs); + closeStatement(ps); + } + } + /** *

* Insert a fired trigger. diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/oracle/OracleDelegate.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/oracle/OracleDelegate.java index 048f315a5..dfcbef3fc 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/oracle/OracleDelegate.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/jdbcjobstore/oracle/OracleDelegate.java @@ -318,6 +318,7 @@ public class OracleDelegate extends StdJDBCDelegate { ps.setInt(13, trigger.getMisfireInstruction()); ps.setBinaryStream(14, null, 0); ps.setInt(15, trigger.getPriority()); + ps.setString(16, trigger.getAppointId()); insertResult = ps.executeUpdate(); diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/triggers/AbstractTrigger.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/triggers/AbstractTrigger.java index 1305a8412..572475908 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/triggers/AbstractTrigger.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/impl/triggers/AbstractTrigger.java @@ -75,6 +75,8 @@ public abstract class AbstractTrigger implements OperableTrig * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + private String appointId; + private String name; private String group = Scheduler.DEFAULT_GROUP; @@ -251,6 +253,16 @@ public abstract class AbstractTrigger implements OperableTrig this.key = null; } + @Override + public String getAppointId() { + return this.appointId; + } + + @Override + public void setAppointId(String appointId) { + this.appointId = appointId; + } + public void setKey(TriggerKey key) { setName(key.getName()); setGroup(key.getGroup()); @@ -873,18 +885,19 @@ public abstract class AbstractTrigger implements OperableTrig } return copy; } - + public TriggerBuilder getTriggerBuilder() { return TriggerBuilder.newTrigger() - .forJob(getJobKey()) - .modifiedByCalendar(getCalendarName()) - .usingJobData(getJobDataMap()) - .withDescription(getDescription()) - .endAt(getEndTime()) - .withIdentity(getKey()) - .withPriority(getPriority()) - .startAt(getStartTime()) - .withSchedule(getScheduleBuilder()); + .appointId(getAppointId()) + .forJob(getJobKey()) + .modifiedByCalendar(getCalendarName()) + .usingJobData(getJobDataMap()) + .withDescription(getDescription()) + .endAt(getEndTime()) + .withIdentity(getKey()) + .withPriority(getPriority()) + .startAt(getStartTime()) + .withSchedule(getScheduleBuilder()); } public abstract ScheduleBuilder getScheduleBuilder(); diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/simpl/RAMJobStore.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/simpl/RAMJobStore.java index e0db3e4df..991bd0e49 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/simpl/RAMJobStore.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/simpl/RAMJobStore.java @@ -139,6 +139,16 @@ public class RAMJobStore implements JobStore { return log; } + @Override + public void setCurrentId(String currentId) { + //do nothing + } + + @Override + public void changeAppointId(String oldId, String newId) { + //do nothing + } + /** *

* Called by the QuartzScheduler before the JobStore is diff --git a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/spi/JobStore.java b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/spi/JobStore.java index fe4026ce8..570199d29 100644 --- a/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/spi/JobStore.java +++ b/fine-quartz/src/main/java/com/fr/third/v2/org/quartz/spi/JobStore.java @@ -68,6 +68,19 @@ public interface JobStore { * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + /** + * 设置当前节点id + */ + void setCurrentId(String currentId); + + /** + * 切换指定节点id + * @param oldId 旧id + * @param newId 新id + */ + void changeAppointId(String oldId, String newId); + + /** * Called by the QuartzScheduler before the JobStore is * used, in order to give the it a chance to initialize. diff --git a/fine-spring/pom.xml b/fine-spring/pom.xml index 8c03f0952..5fa28d6c9 100644 --- a/fine-spring/pom.xml +++ b/fine-spring/pom.xml @@ -65,7 +65,7 @@ fine-javax-annotation ${revision} - 以下是lib的本地jar包依赖<--> + libıjar<--> com.fr.third aopalliance diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..992aad557 --- /dev/null +++ b/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + fine-hibernate + fine-druid + > + + + com.fr.maven + finereport-maven + 10.0 + ../finereport-maven + + + com.fr.third + base-third-code + ${branch} + pom + + \ No newline at end of file