Merge "Issue #1958 Refactoring to improve performance of RedbookDecoder." into omaha_13.4.1

Former-commit-id: 1c9529ab22 [formerly c4d7fef197] [formerly 186571ae67] [formerly da98c61c36 [formerly 186571ae67 [formerly 0b43ec3c32d77f31645b4980aa56512c3d753282]]]
Former-commit-id: da98c61c36
Former-commit-id: d35baaf47590466136bc7619335c5d5434fe3fe1 [formerly 6b1f4a69c1]
Former-commit-id: 8f98b7581b
This commit is contained in:
Richard Peter 2013-05-01 12:28:58 -05:00 committed by Gerrit Code Review
commit ce03807738
40 changed files with 971 additions and 393 deletions

View file

@ -22,6 +22,7 @@ package com.raytheon.viz.redbook.blocks;
import java.nio.ByteBuffer;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlock;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockHeader;
import com.raytheon.viz.redbook.rsc.RedbookLegend;
import com.raytheon.viz.redbook.rsc.RedbookLegend.Type;
@ -33,6 +34,7 @@ import com.raytheon.viz.redbook.rsc.RedbookLegend.Type;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 18, 2010 #3260 dfriedma Initial creation
* Apr 29, 2013 1958 bgonzale New class RedbookBlockHeader.
*
* </pre>
*
@ -45,8 +47,8 @@ public abstract class AbstractTextBlock extends RedbookBlock {
protected int origXPos;
protected int origYPos;
public AbstractTextBlock(ByteBuffer data) {
super(data);
public AbstractTextBlock(RedbookBlockHeader header, ByteBuffer data) {
super(header, data);
}
public abstract TextBlock getTextBlock();

View file

@ -24,6 +24,7 @@ import java.nio.ByteBuffer;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockHeader;
import com.vividsolutions.jts.geom.Coordinate;
/**
@ -34,6 +35,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 22, 2008 #1162 chammack Initial creation
* Apr 29, 2013 1958 bgonzale New class RedbookBlockHeader.
*
* </pre>
*
@ -45,8 +47,9 @@ public class AlphaNumBlock extends AbstractTextBlock {
private final TextBlock textBlock;
public AlphaNumBlock(ByteBuffer data, MathTransform mt, int maxX, int maxY) {
super(data);
public AlphaNumBlock(RedbookBlockHeader header, ByteBuffer data,
MathTransform mt, int maxX, int maxY) {
super(header, data);
int length = getLength();

View file

@ -24,6 +24,7 @@ import java.nio.ByteBuffer;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockHeader;
import com.vividsolutions.jts.geom.Coordinate;
/**
@ -37,6 +38,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 22, 2008 #1162 chammack Initial creation
* Apr 29, 2013 1958 bgonzale New class RedbookBlockHeader.
*
* </pre>
*
@ -47,8 +49,9 @@ import com.vividsolutions.jts.geom.Coordinate;
public class PlotDataBlock extends AbstractTextBlock {
private TextBlock textBlock;
public PlotDataBlock(ByteBuffer data, MathTransform mt, int maxX, int maxY) {
super(data);
public PlotDataBlock(RedbookBlockHeader header, ByteBuffer data,
MathTransform mt, int maxX, int maxY) {
super(header, data);
/* int mode = ( */data.get() /* & 0xFF) */;

View file

@ -22,6 +22,7 @@ package com.raytheon.viz.redbook.blocks;
import java.nio.ByteBuffer;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlock;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockHeader;
/**
* Implements the redbook plot parameter block
@ -31,6 +32,7 @@ import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlock;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 22, 2008 #1162 chammack Initial creation
* Apr 29, 2013 1958 bgonzale New class RedbookBlockHeader.
*
* </pre>
*
@ -52,9 +54,9 @@ public class PlotParametersBlock extends RedbookBlock {
private int lineWidth;
public PlotParametersBlock(ByteBuffer data) {
public PlotParametersBlock(RedbookBlockHeader header, ByteBuffer data) {
super(data);
super(header, data);
// Set up some reasonable defaults
this.lineWidth = 1;

View file

@ -32,6 +32,7 @@ import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.edex.plugin.redbook.common.blocks.Block_004_017;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockHeader;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
@ -45,6 +46,7 @@ import com.vividsolutions.jts.geom.Point;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 27, 2008 #1162 chammack Initial creation
* Apr 29, 2013 1958 bgonzale New class RedbookBlockHeader.
*
* </pre>
*
@ -58,8 +60,8 @@ public class RedbookProjectionBlock extends Block_004_017 {
*
* @param separator
*/
public RedbookProjectionBlock(ByteBuffer data) {
super(data);
public RedbookProjectionBlock(RedbookBlockHeader header, ByteBuffer data) {
super(header, data);
}

View file

@ -26,6 +26,7 @@ import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlock;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockHeader;
import com.raytheon.viz.redbook.rsc.RedbookLegend;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
@ -40,6 +41,7 @@ import com.vividsolutions.jts.geom.LineString;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* May 22, 2008 #1162 chammack Initial creation
* Apr 29, 2013 1958 bgonzale New class RedbookBlockHeader.
*
* </pre>
*
@ -51,9 +53,10 @@ public class ShortLongVectorsBlock extends RedbookBlock {
protected Geometry geometry;
public ShortLongVectorsBlock(java.nio.ByteBuffer data, MathTransform mt,
public ShortLongVectorsBlock(RedbookBlockHeader header,
java.nio.ByteBuffer data, MathTransform mt,
int maxX, int maxY, RedbookLegend legend) {
super(data);
super(header, data);
List<Geometry> geometries = new ArrayList<Geometry>();
List<Coordinate> coords = new ArrayList<Coordinate>();

View file

@ -39,6 +39,8 @@ import org.opengis.referencing.operation.TransformException;
import com.raytheon.edex.plugin.redbook.common.blocks.Block_004_016;
import com.raytheon.edex.plugin.redbook.common.blocks.DefaultBlock;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockBuilder;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockHeader;
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
import com.raytheon.uf.common.geospatial.MapUtil;
@ -89,6 +91,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* May 29, 2008 #1162 chammack Initial creation
* Jan 28, 2010 #4224 M. Huang Added Line Style, Line Width
* menu choice
* Apr 29, 2013 1958 bgonzale New class RedbookBlockHeader.
*
* </pre>
*
@ -160,19 +163,24 @@ public class RedbookFrame implements IRenderable {
while (dataBuf.hasRemaining()) {
String currBlock = getBlockKey(dataBuf);
RedbookBlockHeader header = RedbookBlockBuilder
.getHeader(dataBuf);
String currBlock = header.blockFactoryKey;
if (currBlock.equals("005_002")) {
// Block that describes plot data
PlotDataBlock pdb = new PlotDataBlock(dataBuf, mt, m, n);
PlotDataBlock pdb = new PlotDataBlock(header, dataBuf,
mt, m, n);
parsedTextBlocks.add(pdb);
} else if (currBlock.equals("005_001")) {
// Block that describes alphanumeric data
AlphaNumBlock pdb = new AlphaNumBlock(dataBuf, mt, m, n);
AlphaNumBlock pdb = new AlphaNumBlock(header, dataBuf,
mt, m, n);
parsedTextBlocks.add(pdb);
} else if (currBlock.equals("004_005")) {
// Block that describes the relative short/long format
ShortLongVectorsBlock vb = new ShortLongVectorsBlock(
dataBuf, mt, m, n, legend);
header, dataBuf, mt, m, n, legend);
try {
this.compiler.handle(vb.getGeometry());
} catch (VizException e) {
@ -188,12 +196,12 @@ public class RedbookFrame implements IRenderable {
}
} else if (currBlock.equals("001_004")) {
// Block that describes the plot parameters
new PlotParametersBlock(dataBuf);
new PlotParametersBlock(header, dataBuf);
// Currently, this is not used in rendering
} else if (currBlock.equals("004_017")) {
// Block that describes the projection
RedbookProjectionBlock vb = new RedbookProjectionBlock(
dataBuf);
header, dataBuf);
String customProjection = null;
try {
@ -264,7 +272,7 @@ public class RedbookFrame implements IRenderable {
}
} else if (currBlock.equals("004_016")) {
// Block that describes the plot space
Block_004_016 vb = new Block_004_016(dataBuf);
Block_004_016 vb = new Block_004_016(header, dataBuf);
// Store off the pixel space
m = vb.getRefM2coord();
@ -277,11 +285,11 @@ public class RedbookFrame implements IRenderable {
|| currBlock.startsWith("002_")) {
// Recognized blocks that we don't do anything with
new DefaultBlock(dataBuf);
new DefaultBlock(header, dataBuf);
} else {
DefaultBlock block = new DefaultBlock(dataBuf);
DefaultBlock block = new DefaultBlock(header, dataBuf);
if (!currBlock.equals("")) {
status.unhandledPackets = true;
@ -618,29 +626,6 @@ public class RedbookFrame implements IRenderable {
}
}
/**
*
* @param dataBuffer
* @return
*/
private static String getBlockKey(ByteBuffer dataBuffer) {
String blockKey = "";
// Must have at least 4 bytes
if (dataBuffer.remaining() > MIN_REMAINING) {
dataBuffer.mark();
// Dummy read for the flags/length
dataBuffer.getShort();
int mode = (dataBuffer.get() & 0xFF);
int subMode = (dataBuffer.get() & 0xFF);
dataBuffer.reset();
blockKey = String.format(MODE_KEY_FMT, mode, subMode);
}
return blockKey;
}
public void dispose() {
if (this.wireframeShape != null) {
this.wireframeShape.dispose();

View file

@ -142,8 +142,8 @@ public class RedbookDecoder extends AbstractDecoder {
+ "- File is not Redbook data. Type is "
+ foreign.dataType);
} else {
report = new RedbookParser(traceId, data, wmoHeader)
.getDecodedRecord();
report = new RedbookParser(traceId, data,
wmoHeader).getDecodedRecord();
}
if (report != null) {
report.setPersistenceTime(new Date());

View file

@ -19,6 +19,7 @@
**/
package com.raytheon.edex.plugin.redbook.common;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
@ -63,6 +64,7 @@ import com.raytheon.uf.common.time.DataTime;
* Apr 4, 2013 1846 bkowal Added an index on refTime and forecastTime
* 20130408 1293 bkowal Removed references to hdffileid.
* Apr 12, 2013 1857 bgonzale Added SequenceGenerator annotation.
* Apr 29, 2013 1958 bgonzale Added equals and hashcode.
* </pre>
*
* @author jkorman
@ -363,4 +365,98 @@ public class RedbookRecord extends PersistablePluginDataObject
return other;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result
+ ((corIndicator == null) ? 0 : corIndicator.hashCode());
result = prime * result
+ ((fcstHours == null) ? 0 : fcstHours.hashCode());
result = prime * result + ((fileId == null) ? 0 : fileId.hashCode());
result = prime * result
+ ((originatorId == null) ? 0 : originatorId.hashCode());
result = prime * result
+ ((productId == null) ? 0 : productId.hashCode());
result = prime * result + Arrays.hashCode(redBookData);
result = prime * result
+ ((retentionHours == null) ? 0 : retentionHours.hashCode());
result = prime * result + ((timeObs == null) ? 0 : timeObs.hashCode());
result = prime * result
+ ((wmoCCCCdt == null) ? 0 : wmoCCCCdt.hashCode());
result = prime * result
+ ((wmoTTAAii == null) ? 0 : wmoTTAAii.hashCode());
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
RedbookRecord other = (RedbookRecord) obj;
if (corIndicator == null) {
if (other.corIndicator != null)
return false;
} else if (!corIndicator.equals(other.corIndicator))
return false;
if (fcstHours == null) {
if (other.fcstHours != null)
return false;
} else if (!fcstHours.equals(other.fcstHours))
return false;
if (fileId == null) {
if (other.fileId != null)
return false;
} else if (!fileId.equals(other.fileId))
return false;
if (originatorId == null) {
if (other.originatorId != null)
return false;
} else if (!originatorId.equals(other.originatorId))
return false;
if (productId == null) {
if (other.productId != null)
return false;
} else if (!productId.equals(other.productId))
return false;
if (!Arrays.equals(redBookData, other.redBookData))
return false;
if (retentionHours == null) {
if (other.retentionHours != null)
return false;
} else if (!retentionHours.equals(other.retentionHours))
return false;
if (timeObs == null) {
if (other.timeObs != null)
return false;
} else if (!timeObs.equals(other.timeObs))
return false;
if (wmoCCCCdt == null) {
if (other.wmoCCCCdt != null)
return false;
} else if (!wmoCCCCdt.equals(other.wmoCCCCdt))
return false;
if (wmoTTAAii == null) {
if (other.wmoTTAAii != null)
return false;
} else if (!wmoTTAAii.equals(other.wmoTTAAii))
return false;
return true;
}
}

View file

@ -30,6 +30,8 @@ import java.nio.ByteBuffer;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080512 1131 jkorman Initial implementation.
* Apr 29, 2013 1958 bgonzale Added class RedbookBlockHeader,
* and nested Factory class.
*
* </pre>
*
@ -39,12 +41,21 @@ import java.nio.ByteBuffer;
public class Block_004_004 extends RedbookBlock {
public static class Factory implements RedbookBlockFactory {
@Override
public RedbookBlock createBlock(RedbookBlockHeader header,
ByteBuffer data) {
return new Block_004_004(header, data);
}
}
/**
*
* @param header
* @param separator
*/
public Block_004_004(ByteBuffer data) {
super(data);
public Block_004_004(RedbookBlockHeader header, ByteBuffer data) {
super(header, data);
populate(data);
if(hasChkSum()) {
data.getShort();
@ -53,9 +64,7 @@ public class Block_004_004 extends RedbookBlock {
private void populate(ByteBuffer data) {
if(hasLength()) {
for(int i = 0;i < getLength()-2;i++) {
data.getShort();
}
dropShortsFromTheBuffer(data);
}
}

View file

@ -21,30 +21,42 @@ package com.raytheon.edex.plugin.redbook.common.blocks;
import java.nio.ByteBuffer;
/**TODO Add Description
/**
* TODO Add Description
*
* <pre>
*
*
* SOFTWARE HISTORY
*
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080512 1131 jkorman Initial implementation.
* Apr 29, 2013 1958 bgonzale Added class RedbookBlockHeader,
* and nested Factory class.
*
* </pre>
*
*
* @author jkorman
* @version 1.0
* @version 1.0
*/
public class Block_004_005 extends RedbookBlock {
public static class Factory implements RedbookBlockFactory {
@Override
public RedbookBlock createBlock(RedbookBlockHeader header,
ByteBuffer data) {
return new Block_004_005(header, data);
}
}
/**
*
* @param header
* @param separator
*/
public Block_004_005(ByteBuffer data) {
super(data);
public Block_004_005(RedbookBlockHeader header, ByteBuffer data) {
super(header, data);
populate(data);
if(hasChkSum()) {
data.getShort();
@ -52,10 +64,8 @@ public class Block_004_005 extends RedbookBlock {
}
private void populate(ByteBuffer data) {
if(hasLength()) {
for(int i = 0;i < getLength()-2;i++) {
data.getShort();
}
if (hasLength()) {
dropShortsFromTheBuffer(data);
}
}

View file

@ -21,20 +21,23 @@ package com.raytheon.edex.plugin.redbook.common.blocks;
import java.nio.ByteBuffer;
/**TODO Add Description
/**
* TODO Add Description
*
* <pre>
*
*
* SOFTWARE HISTORY
*
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080512 1131 jkorman Initial implementation.
* Apr 29, 2013 1958 bgonzale Added class RedbookBlockHeader,
* and nested Factory class.
*
* </pre>
*
*
* @author jkorman
* @version 1.0
* @version 1.0
*/
public class Block_004_016 extends RedbookBlock {
@ -65,12 +68,21 @@ public class Block_004_016 extends RedbookBlock {
private int evtMinute;
public static class Factory implements RedbookBlockFactory {
@Override
public RedbookBlock createBlock(RedbookBlockHeader header,
ByteBuffer data) {
return new Block_004_016(header, data);
}
}
/**
*
* @param header
* @param separator
*/
public Block_004_016(ByteBuffer data) {
super(data);
public Block_004_016(RedbookBlockHeader header, ByteBuffer data) {
super(header, data);
populate(data);
if(hasChkSum()) {
data.getShort();

View file

@ -21,20 +21,23 @@ package com.raytheon.edex.plugin.redbook.common.blocks;
import java.nio.ByteBuffer;
/**TODO Add Description
/**
* TODO Add Description
*
* <pre>
*
*
* SOFTWARE HISTORY
*
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080512 1131 jkorman Initial implementation.
* Apr 29, 2013 1958 bgonzale Added class RedbookBlockHeader,
* and nested Factory class.
*
* </pre>
*
*
* @author jkorman
* @version 1.0
* @version 1.0
*/
public class Block_004_017 extends RedbookBlock {
@ -55,12 +58,21 @@ public class Block_004_017 extends RedbookBlock {
private String projName;
public static class Factory implements RedbookBlockFactory {
@Override
public RedbookBlock createBlock(RedbookBlockHeader header,
ByteBuffer data) {
return new Block_004_017(header, data);
}
}
/**
*
* @param header
* @param separator
*/
public Block_004_017(ByteBuffer data) {
super(data);
public Block_004_017(RedbookBlockHeader header, ByteBuffer data) {
super(header, data);
populateProj(data);
if(hasChkSum()) {
data.getShort();

View file

@ -21,35 +21,44 @@ package com.raytheon.edex.plugin.redbook.common.blocks;
import java.nio.ByteBuffer;
/**TODO Add Description
/**
* TODO Add Description
*
* <pre>
*
*
* SOFTWARE HISTORY
*
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080512 1131 jkorman Initial implementation.
* Apr 29, 2013 1958 bgonzale Added class RedbookBlockHeader,
* and nested Factory class.
*
* </pre>
*
*
* @author jkorman
* @version 1.0
* @version 1.0
*/
public class DefaultBlock extends RedbookBlock {
public static class Factory implements RedbookBlockFactory {
@Override
public RedbookBlock createBlock(RedbookBlockHeader header,
ByteBuffer data) {
return new DefaultBlock(header, data);
}
}
/**
*
* @param header
* @param separator
*/
public DefaultBlock(ByteBuffer data) {
super(data);
public DefaultBlock(RedbookBlockHeader header, ByteBuffer data) {
super(header, data);
if(hasLength()) {
for(int i = 0;i < getLength()-2;i++) {
data.getShort();
}
dropShortsFromTheBuffer(data);
}
}
@ -58,9 +67,6 @@ public class DefaultBlock extends RedbookBlock {
*/
public StringBuilder toString(StringBuilder sb) {
sb = super.toString(sb);
return sb;
}
}

View file

@ -21,30 +21,42 @@ package com.raytheon.edex.plugin.redbook.common.blocks;
import java.nio.ByteBuffer;
/**TODO Add Description
/**
* TODO Add Description
*
* <pre>
*
*
* SOFTWARE HISTORY
*
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080512 1131 jkorman Initial implementation.
* Apr 29, 2013 1958 bgonzale Added class RedbookBlockHeader,
* and nested Factory class.
*
* </pre>
*
*
* @author jkorman
* @version 1.0
* @version 1.0
*/
public class EndOfProductBlock extends RedbookBlock {
public static class Factory implements RedbookBlockFactory {
@Override
public RedbookBlock createBlock(RedbookBlockHeader header,
ByteBuffer data) {
return new EndOfProductBlock(header, data);
}
}
/**
*
* @param header
* @param separator
*/
public EndOfProductBlock(ByteBuffer data) {
super(data);
public EndOfProductBlock(RedbookBlockHeader header, ByteBuffer data) {
super(header, data);
if(hasChkSum()) {
data.getShort();
}
@ -63,9 +75,6 @@ public class EndOfProductBlock extends RedbookBlock {
*/
public StringBuilder toString(StringBuilder sb) {
sb = super.toString(sb);
return sb;
}
}

View file

@ -24,21 +24,23 @@ import java.util.Calendar;
import com.raytheon.uf.edex.decodertools.time.TimeTools;
/**TODO Add Description
/**
* TODO Add Description
*
* <pre>
*
*
* SOFTWARE HISTORY
*
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080512 1131 jkorman Initial implementation.
* Apr 29, 2013 1958 bgonzale Added class RedbookBlockHeader,
* and nested Factory class.
*
* </pre>
*
*
* @author jkorman
* @version 1.0
* @version 1.0
*/
public class ProductIdBlock extends RedbookBlock {
@ -66,12 +68,20 @@ public class ProductIdBlock extends RedbookBlock {
private Integer fcstHours;
public static class Factory implements RedbookBlockFactory {
@Override
public RedbookBlock createBlock(RedbookBlockHeader header,
ByteBuffer data) {
return new ProductIdBlock(header, data);
}
}
/**
*
* @param separator
*/
public ProductIdBlock(ByteBuffer data) {
super(data);
public ProductIdBlock(RedbookBlockHeader header, ByteBuffer data) {
super(header, data);
int blockLen = (hasChkSum()) ? BLOCK_LEN : BLOCK_LEN - 2;
if(data.remaining() >= blockLen) {

View file

@ -29,17 +29,19 @@ import org.apache.commons.logging.LogFactory;
*
*
* <pre>
*
*
* SOFTWARE HISTORY
*
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080512 1131 jkorman Initial implementation.
* Apr 29, 2013 1958 bgonzale Added class RedbookBlockHeader,
* and nested Factory interface.
*
* </pre>
*
*
* @author jkorman
* @version 1.0
* @version 1.0
*/
public abstract class RedbookBlock {
@ -57,28 +59,28 @@ public abstract class RedbookBlock {
private boolean hasChkSum = false;
private RedbookBlockHeader header;
private final int length;
private final int mode;
private final int subMode;
public interface RedbookBlockFactory {
public abstract RedbookBlock createBlock(RedbookBlockHeader header,
ByteBuffer data);
}
/**
*
* @param separator
*/
public RedbookBlock(ByteBuffer data) {
public RedbookBlock(RedbookBlockHeader header, ByteBuffer data) {
int hdr = (data.getShort() & 0xFFFF);
hasLength = (hdr & LEN_MASK) == 0;
hasChkSum = (hdr & CHKSUM_MASK) == 0;
this.header = header;
mode = (data.get() & 0xFF);
subMode = (data.get() & 0xFF);
hasLength = (this.header.hdr & LEN_MASK) == 0;
length = (hasLength) ? (hdr & LENGTH_MASK) : -1;
hasChkSum = (this.header.hdr & CHKSUM_MASK) == 0;
length = (hasLength) ? (this.header.hdr & LENGTH_MASK) : -1;
}
public boolean isEndBlock() {
@ -96,14 +98,14 @@ public abstract class RedbookBlock {
* @return the mode
*/
public int getMode() {
return mode;
return this.header.mode;
}
/**
* @return the subMode
*/
public int getSubMode() {
return subMode;
return this.header.subMode;
}
/**
@ -142,7 +144,7 @@ public abstract class RedbookBlock {
sb.append((hasChkSum) ? 'C' : '.');
sb.append(':');
sb.append(String.format("%05d:mode=%02X:submode=%02X",length,mode,subMode));
sb.append(String.format("%05d:mode=%02X:submode=%02X",length,header.mode,header.subMode));
return sb;
}
@ -165,5 +167,23 @@ public abstract class RedbookBlock {
}
return f;
}
/**
* @return true if this is a Product Id block; false otherwise.
*/
public boolean isProductId() {
return header.isProductId();
}
/**
* @return true if this is a Product Id block; false otherwise.
*/
public boolean isUpperAirPlot() {
return header.isUpperAirPlot();
}
protected void dropShortsFromTheBuffer(ByteBuffer data) {
int newPosition = (data.position() + ((getLength() - 2) << 1));
data.position(newPosition);
}
}

View file

@ -0,0 +1,143 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.redbook.common.blocks;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlock.RedbookBlockFactory;
import com.raytheon.edex.plugin.redbook.decoder.RedbookFcstMap;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.util.PropertiesUtil;
import com.raytheon.uf.common.util.ReflectionException;
import com.raytheon.uf.common.util.ReflectionUtil;
/**
*
* Build RedbookBlocks from a buffer.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080516 1131 jkorman Initial Coding.
* Apr 29, 2013 1958 bgonzale Added class RedbookBlockHeader,
* and moved reflective calls to the
* mapping population method. Map now
* contains factory objects.
*
* </pre>
*
* @author jkorman
* @version 1.0
*/
public class RedbookBlockBuilder {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(RedbookFcstMap.class);
private static final int MIN_REMAINING = 4;
private static final String FACTORY_NAME = "$Factory";
private final Map<String, RedbookBlockFactory> blockFactoryMap = new HashMap<String, RedbookBlockFactory>();
public RedbookBlockBuilder() {
populateMappings();
}
/**
*
* @return
*/
public RedbookBlock getBlock(ByteBuffer dataBuffer) {
RedbookBlock blockInstance = null;
if (dataBuffer != null) {
RedbookBlockHeader header = getHeader(dataBuffer);
RedbookBlockFactory factory = blockFactoryMap
.get(header.blockFactoryKey);
if (factory == null) {
blockInstance = new DefaultBlock(header, dataBuffer);
} else {
blockInstance = factory.createBlock(header, dataBuffer);
}
}
return blockInstance;
}
/**
*
* @param dataBuffer
* @return
*/
public static RedbookBlockHeader getHeader(ByteBuffer dataBuffer) {
RedbookBlockHeader header = null;
short rawHdr = dataBuffer.getShort();
byte rawMode = dataBuffer.get();
byte rawSubMode = dataBuffer.get();
// Must have at least MIN_REMAINING
if (dataBuffer.remaining() >= MIN_REMAINING) {
header = new RedbookBlockHeader(rawHdr, rawMode, rawSubMode);
} else {
header = RedbookBlockHeader.DEFAULT;
}
return header;
}
/**
*
*/
private void populateMappings() {
final String redbookBlockProperties = "/res/conf/RedbookBlocks.properties";
try {
Properties redbookClassProps = PropertiesUtil.read(this.getClass()
.getResourceAsStream(redbookBlockProperties));
for (String key : redbookClassProps.stringPropertyNames()) {
String factoryClassName = redbookClassProps.get(key)
+ FACTORY_NAME;
try {
RedbookBlockFactory factory = ReflectionUtil
.newInstanceOfAssignableType(
RedbookBlockFactory.class, factoryClassName);
blockFactoryMap.put((String) key, factory);
} catch (ReflectionException e) {
statusHandler.error("Could not instantiate "
+ factoryClassName, e);
}
}
} catch (IOException e) {
statusHandler.error(
"Could not load properties from the property file "
+ redbookBlockProperties, e);
}
}
}

View file

@ -1,193 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.redbook.common.blocks;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* TODO Add Description
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 20080516 1131 jkorman Initial Coding.
*
* </pre>
*
* @author jkorman
* @version 1.0
*/
public class RedbookBlockFactory {
private Log logger = LogFactory.getLog(getClass());
private static final String MODE_KEY_FMT = "%03d_%03d";
private static final String DEFAULT_KEY = "default";
private static final int MIN_REMAINING = 4;
private Properties RptClassMap;
private static RedbookBlockFactory factoryInstance = null;
private boolean loaded = false;
private RedbookBlockFactory() {
populateMappings();
}
/**
*
* @return
*/
public RedbookBlock getBlock(ByteBuffer dataBuffer) {
RedbookBlock blockInstance = null;
if (dataBuffer != null) {
String blockId = RptClassMap.getProperty(getBlockKey(dataBuffer));
try {
if ((blockId != null) && (!DEFAULT_KEY.equals(blockId))) {
Class<?> c = null;
try {
c = Class.forName(blockId);
try {
Constructor<?> con = c
.getConstructor(ByteBuffer.class);
blockInstance = (RedbookBlock) con
.newInstance(dataBuffer);
} catch (InstantiationException e) {
logger.error("Could not instantiate " + blockId, e);
} catch (IllegalAccessException e) {
logger.error("Illegal access " + blockId, e);
} catch (SecurityException e) {
logger.error("Could not instantiate " + blockId, e);
} catch (NoSuchMethodException e) {
logger.error("Could not instantiate " + blockId, e);
} catch (IllegalArgumentException e) {
logger.error("Could not instantiate " + blockId, e);
} catch (InvocationTargetException e) {
logger.error("Could not instantiate " + blockId, e);
}
} catch (ClassNotFoundException e1) {
logger.error("No class found for " + blockId);
}
}
} finally {
if (blockInstance == null) {
blockInstance = new DefaultBlock(dataBuffer);
}
}
}
return blockInstance;
}
/**
* @return the loaded
*/
public boolean isLoaded() {
return loaded;
}
/**
*
* @return
*/
public static synchronized RedbookBlockFactory getInstance() {
if (factoryInstance == null) {
factoryInstance = new RedbookBlockFactory();
}
return factoryInstance;
}
/**
*
* @param dataBuffer
* @return
*/
private String getBlockKey(ByteBuffer dataBuffer) {
String blockKey = DEFAULT_KEY;
// Must have at least MIN_REMAINING
if (dataBuffer.remaining() >= MIN_REMAINING) {
dataBuffer.mark();
// Dummy read for the flags/length
dataBuffer.getShort();
int mode = (dataBuffer.get() & 0xFF);
int subMode = (dataBuffer.get() & 0xFF);
dataBuffer.reset();
blockKey = String.format(MODE_KEY_FMT, mode, subMode);
}
return blockKey;
}
/**
*
*/
private void populateMappings() {
InputStream strm = null;
BufferedReader bf = null;
RptClassMap = new Properties();
try {
try {
strm = this.getClass().getResourceAsStream(
"/res/conf/RedbookBlocks.properties");
if (strm != null) {
bf = new BufferedReader(new InputStreamReader(strm));
RptClassMap.load(bf);
loaded = true;
} else {
loaded = false;
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
} finally {
if (bf != null) {
try {
bf.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
}

View file

@ -0,0 +1,88 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.redbook.common.blocks;
/**
*
* RedbookBlock header mode and submode. Also contains generated key based on
* mode and submode.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 25 APR 2013 bgonzale Initial Coding.
*
* </pre>
*
* @author bgonzale
* @version 1.0
*/
public class RedbookBlockHeader {
private static final String DEFAULT_KEY = "default";
private static final String MODE_KEY_FMT = "%03d_%03d";
public static final RedbookBlockHeader DEFAULT = new RedbookBlockHeader();
public final int hdr;
public final int mode;
public final int subMode;
public final String blockFactoryKey;
/**
* @param hdr
* @param mode
* @param subMode
* @param blockKey
*/
public RedbookBlockHeader(short hdrRaw, byte modeRaw, byte subModeRaw) {
super();
this.hdr = (hdrRaw & 0xFFFF);
this.mode = (modeRaw & 0xFF);
this.subMode = (subModeRaw & 0xFF);
this.blockFactoryKey = String.format(MODE_KEY_FMT, mode, subMode);
}
private RedbookBlockHeader() {
super();
this.hdr = 0;
this.mode = 0;
this.subMode = 0;
this.blockFactoryKey = DEFAULT_KEY;
}
public static boolean isDefaultBlockId(String blockId) {
return DEFAULT_KEY.equals(blockId);
}
public boolean isProductId() {
return (mode == 1) && (subMode == 1);
}
public boolean isUpperAirPlot() {
return (mode == 2) && (subMode == 3);
}
}

View file

@ -19,9 +19,7 @@
**/
package com.raytheon.edex.plugin.redbook.decoder;
import java.io.File;
import java.util.HashMap;
import java.util.Properties;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -29,23 +27,30 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.localization.FileUpdatedMessage;
import com.raytheon.uf.common.localization.ILocalizationFileObserver;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.LocalizationFile;
import com.raytheon.uf.common.localization.PathManagerFactory;
import com.raytheon.uf.common.serialization.ISerializableObject;
import com.raytheon.uf.common.serialization.SerializationException;
import com.raytheon.uf.common.serialization.SerializationUtil;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
* Add fcsttime
* Mapping of WMO header TTAAII values to forecast hour attributes.
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ----------- ----------- --------------------------
* 20101022 6424 kshrestha Add fcsttime
* Apr 29, 2013 1958 bgonzale Map is loaded once, and then
* not loaded again unless the mapping
* file changes.
*
* </pre>
*
@ -58,6 +63,8 @@ public class RedbookFcstMap implements ISerializableObject {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(RedbookFcstMap.class);
private static final String REDBOOK_FCST_MAP_XML = "redbook/redbookFcstMap.xml";
@XmlAccessorType(XmlAccessType.FIELD)
public static class MapFcstHr {
@XmlElement(required = false)
@ -73,26 +80,57 @@ public class RedbookFcstMap implements ISerializableObject {
public Integer binOffset;
}
public HashMap<String, MapFcstHr> mapping;
private static RedbookFcstMap instance;
public static File xmlFile;
private HashMap<String, MapFcstHr> mapping;
public static Properties filesXml = new Properties();
private RedbookFcstMap() {
}
public static RedbookFcstMap load() throws Exception {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext ctx = pathMgr.getContext(
LocalizationContext.LocalizationType.EDEX_STATIC,
LocalizationContext.LocalizationLevel.BASE);
private static RedbookFcstMap load(LocalizationFile xmlFile) {
RedbookFcstMap loadedMap = null;
try {
xmlFile = pathMgr.getFile(ctx, "redbook/redbookFcstMap.xml");
RedbookFcstMap map = (RedbookFcstMap) SerializationUtil
.jaxbUnmarshalFromXmlFile(xmlFile.getAbsolutePath());
return map;
} catch (Exception e) {
loadedMap = SerializationUtil.jaxbUnmarshalFromXmlFile(
RedbookFcstMap.class, xmlFile.getFile().getAbsolutePath());
} catch (SerializationException e) {
statusHandler.handle(Priority.PROBLEM, e.getMessage(), e);
throw e;
}
return loadedMap;
}
/**
* @param key
* @return The Map Forecast Hour attributes associated with the key; null if
* none found.
*/
public MapFcstHr get(String key) {
return this.mapping.get(key);
}
/**
* Get the instance of the Map.
*
* @return the instance.
*/
public static synchronized RedbookFcstMap getInstance() {
if (instance == null) {
IPathManager pathMgr = PathManagerFactory.getPathManager();
LocalizationContext ctx = pathMgr.getContext(
LocalizationContext.LocalizationType.EDEX_STATIC,
LocalizationContext.LocalizationLevel.BASE);
final LocalizationFile xmlFile = pathMgr.getLocalizationFile(ctx,
REDBOOK_FCST_MAP_XML);
instance = load(xmlFile);
xmlFile.addFileUpdatedObserver(new ILocalizationFileObserver() {
@Override
public void fileUpdated(FileUpdatedMessage message) {
RedbookFcstMap updatedMap = load(xmlFile);
instance.mapping.clear();
instance.mapping.putAll(updatedMap.mapping);
}
});
}
return instance;
}
}

View file

@ -32,7 +32,7 @@ import org.apache.commons.logging.LogFactory;
import com.raytheon.edex.plugin.redbook.common.RedbookRecord;
import com.raytheon.edex.plugin.redbook.common.blocks.ProductIdBlock;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlock;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockFactory;
import com.raytheon.edex.plugin.redbook.common.blocks.RedbookBlockBuilder;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.edex.decodertools.time.TimeTools;
import com.raytheon.uf.edex.wmo.message.WMOHeader;
@ -51,6 +51,7 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
* 20080529 1131 jkorman Added traceId, implemented in logger.
* 20101022 6424 kshrestha Added fcsttime
* 20110516 8296 mhuang fixed fcsttime problem
* Apr 29, 2013 1958 bgonzale Refactored to improve performance.
* </pre>
*
* @author jkorman
@ -58,6 +59,8 @@ import com.raytheon.uf.edex.wmo.message.WMOHeader;
*/
public class RedbookParser {
private static final RedbookBlockBuilder blockBuilder = new RedbookBlockBuilder();
private final Log logger = LogFactory.getLog(getClass());
// private Calendar issueDate = null;
@ -66,7 +69,7 @@ public class RedbookParser {
private RedbookRecord rRecord;
private final RedbookBlockFactory blockFactory;
private RedbookFcstMap redbookFcstMap = RedbookFcstMap.getInstance();
/**
*
@ -75,8 +78,6 @@ public class RedbookParser {
* @param hdr
*/
public RedbookParser(String traceId, byte[] data, WMOHeader hdr) {
blockFactory = RedbookBlockFactory.getInstance();
rRecord = internalParse(traceId, data, hdr);
if (rRecord != null) {
@ -137,13 +138,16 @@ public class RedbookParser {
ByteBuffer dataBuf = ByteBuffer.wrap(redbookMsg);
ProductIdBlock productId = null;
redbookDocument = new ArrayList<RedbookBlock>();
while (dataBuf.hasRemaining()) {
RedbookBlock currBlock = null;
try {
currBlock = blockFactory.getBlock(dataBuf);
currBlock = blockBuilder.getBlock(dataBuf);
redbookDocument.add(currBlock);
@ -154,7 +158,7 @@ public class RedbookParser {
System.arraycopy(redbookMsg, 0, redBookData, 0, endPos);
record.setRedBookData(redBookData);
break;
} else if (currBlock.getMode() == 2 && currBlock.getSubMode() == 3) {
} else if (currBlock.isUpperAirPlot()) {
/*
* Upper air plots are malformed and require special
* handling to extract the data. If we get this far, it is
@ -166,35 +170,35 @@ public class RedbookParser {
break;
}
}
if (currBlock.isProductId()) {
productId = (ProductIdBlock) currBlock;
}
} catch (BufferUnderflowException bue) {
logger.error(traceId + "- Out of data");
logger.error(traceId + "- Out of data", bue);
return record;
} catch (Exception e) {
logger.error(traceId + "- Error in parser", e);
return record;
}
}
if (record != null) {
for (RedbookBlock block : redbookDocument) {
if ((block.getMode() == 1) && (block.getSubMode() == 1)) {
ProductIdBlock id = (ProductIdBlock) block;
record.setTimeObs(id.getProductFileTime());
record.setRetentionHours(id.getRetentionHours());
if (productId != null) {
record.setTimeObs(productId.getProductFileTime());
record.setRetentionHours(productId.getRetentionHours());
record.setFileId(id.getFileIndicator());
record.setProductId(id.getProductId());
record.setOriginatorId(id.getOriginatorId());
record.setFileId(productId.getFileIndicator());
record.setProductId(productId.getProductId());
record.setOriginatorId(productId.getOriginatorId());
/* record.setFcstHours(id.getFcstHours()); */
record.setFcstHours(getForecastTime(traceId, hdr));
int fcstTime = this.getForecastTime(traceId, hdr);
if (fcstTime == 0)
record.setFcstHours(fcstTime);
record.setTraceId(traceId);
}
/* record.setFcstHours(id.getFcstHours()); */
record.setFcstHours(getForecastTime(traceId, hdr));
record.setTraceId(traceId);
}
} else {
logger.info(traceId + "- No EndOfProductBlock found");
}
@ -202,41 +206,32 @@ public class RedbookParser {
return record;
}
public int getForecastTime(String traceId, WMOHeader hdr)
{
RedbookFcstMap map;
try {
map = RedbookFcstMap.load();
if (map != null){
RedbookFcstMap.MapFcstHr xmlInfo = map.mapping.get(hdr.getTtaaii());
if (xmlInfo != null && xmlInfo.fcstHR != null && !xmlInfo.fcstHR.isEmpty())
return(Integer.parseInt(xmlInfo.fcstHR));
}
return 0;
} catch (Exception e) {
logger.error(traceId + " - Error in parser - mappingFCST: ", e);
public int getForecastTime(String traceId, WMOHeader hdr) {
RedbookFcstMap.MapFcstHr xmlInfo = redbookFcstMap.get(hdr.getTtaaii());
if (xmlInfo != null && xmlInfo.fcstHR != null
&& !xmlInfo.fcstHR.isEmpty()) {
return (Integer.parseInt(xmlInfo.fcstHR));
}
return 0;
}
return 0;
}
public long getBinnedTime(String traceId, WMOHeader hdr, long timeMillis) {
try {
long period = 43200 * 1000; // default period is 12 hours
long offset = 0;
RedbookFcstMap map = RedbookFcstMap.load();
if (map != null) {
RedbookFcstMap.MapFcstHr xmlInfo = map.mapping.get(hdr
.getTtaaii());
if (xmlInfo != null) {
/* Does not support AWIPS 1 semantics of "period < 0 means
* apply offset first".
*/
if (xmlInfo.binPeriod != null && xmlInfo.binPeriod > 0)
period = (long) xmlInfo.binPeriod * 1000;
if (xmlInfo.binOffset != null)
offset = (long) xmlInfo.binOffset * 1000;
}
RedbookFcstMap.MapFcstHr xmlInfo = redbookFcstMap.get(hdr
.getTtaaii());
if (xmlInfo != null) {
/*
* Does not support AWIPS 1 semantics of "period < 0 means apply
* offset first".
*/
if (xmlInfo.binPeriod != null && xmlInfo.binPeriod > 0)
period = (long) xmlInfo.binPeriod * 1000;
if (xmlInfo.binOffset != null)
offset = (long) xmlInfo.binOffset * 1000;
}
timeMillis = (timeMillis / period) * period + offset;

View file

@ -73,6 +73,7 @@
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/com.raytheon.uf.common.units"/>
<classpathentry exported="true" kind="src" path="/com.raytheon.uf.viz.stats"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/org.dom4j"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/com.raytheon.edex.plugin.redbook"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/com.raytheon.uf.edex.plugin.level"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/com.raytheon.uf.common.dataplugin.level"/>
<classpathentry kind="src" path="/com.raytheon.uf.common.dataplugin.ffmp"/>
@ -91,5 +92,6 @@
</attributes>
</classpathentry>
<classpathentry kind="lib" path="lib/javax.servlet_2.5.0.v200910301333.jar"/>
<classpathentry kind="lib" path="/com.raytheon.edex.plugin.redbook/res/conf"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,9 @@
traceId
PMNA01_KWNS_220049_47355211.rb
ingestfilename
./data/Redbook/PMNA01_KWNS_220049_47355211.rb.Input
camelbeanmethodname
/awips2/edex/data/manual/PMNA01_KWNS_220049_47355211.rb
camelfilelastmodified
PMNA01_KWNS_220049_47355211.rb
jmsreplyto

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><redbookRecord fileId="72" productId="PXS0024CNENHOL1" fcstHours="0" retentionHours="0" wmoCCCCdt=" KWNS 220049" wmoTTAAii="PMNA01" timeObs="2013-04-22T00:49:00Z" insertTime="2013-04-24T22:21:16.373Z" pluginName="com.raytheon.edex.plugin.redbook.RedbookDecoderTest" dataURI="/com.raytheon.edex.plugin.redbook.RedbookDecoderTest/2013-04-22_00:00:00.0/PMNA01/PXS0024CNENHOL1/null/null/0/72"><dataTime levelValue="-1.0" fcstTime="0" refTime="2013-04-21T19:00:00-05:00"><validPeriod end="2013-04-21T19:00:00-05:00" start="2013-04-21T19:00:00-05:00"/></dataTime></redbookRecord>

View file

@ -0,0 +1,9 @@
traceId
PSBB08_KWNH_220000_46836601.rb
ingestfilename
./data/Redbook/PSBB08_KWNH_220000_46836601.rb
camelbeanmethodname
/awips2/edex/data/manual/PSBB08_KWNH_220000_46836601.rb
camelfilelastmodified
PSBB08_KWNH_220000_46836601.rb
jmsreplyto

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><redbookRecord fileId="72" productId="PISF024CNSNOHVY" fcstHours="24" retentionHours="0" wmoCCCCdt=" KWNH 220000" wmoTTAAii="PSBB08" timeObs="2013-04-22T00:00:00Z" insertTime="2013-04-24T22:21:16.484Z" pluginName="com.raytheon.edex.plugin.redbook.RedbookDecoderTest" dataURI="/com.raytheon.edex.plugin.redbook.RedbookDecoderTest/2013-04-22_00:00:00.0_(24)/PSBB08/PISF024CNSNOHVY/null/null/24/72"><dataTime levelValue="-1.0" fcstTime="86400" refTime="2013-04-21T19:00:00-05:00"><validPeriod end="2013-04-22T19:00:00-05:00" start="2013-04-22T19:00:00-05:00"/><utilityFlags>FCST_USED</utilityFlags></dataTime></redbookRecord>

View file

@ -0,0 +1,9 @@
traceId
PYMA20_KWBC_220000_47396312.rb
ingestfilename
./data/Redbook/PYMA20_KWBC_220000_47396312
camelbeanmethodname
/awips2/edex/data/manual/PYMA20_KWBC_220000_47396312.rb
camelfilelastmodified
PYMA20_KWBC_220000_47396312.rb
jmsreplyto

View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><redbookRecord fileId="72" productId="PE20000NAPLTUPA" fcstHours="0" retentionHours="0" wmoCCCCdt=" KWBC 220000" wmoTTAAii="PYMA20" timeObs="2013-04-22T01:16:00Z" insertTime="2013-04-24T22:21:16.541Z" pluginName="com.raytheon.edex.plugin.redbook.RedbookDecoderTest" dataURI="/com.raytheon.edex.plugin.redbook.RedbookDecoderTest/2013-04-22_00:00:00.0/PYMA20/PE20000NAPLTUPA/null/null/0/72"><dataTime levelValue="-1.0" fcstTime="0" refTime="2013-04-21T19:00:00-05:00"><validPeriod end="2013-04-21T19:00:00-05:00" start="2013-04-21T19:00:00-05:00"/></dataTime></redbookRecord>

View file

@ -0,0 +1,4 @@
001_001=com.raytheon.edex.plugin.redbook.common.blocks.ProductIdBlock
001_002=com.raytheon.edex.plugin.redbook.common.blocks.EndOfProductBlock
004_016=com.raytheon.edex.plugin.redbook.common.blocks.Block_004_016
004_017=com.raytheon.edex.plugin.redbook.common.blocks.Block_004_017

View file

@ -0,0 +1,286 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.edex.plugin.redbook;
import static org.junit.Assert.assertEquals;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import org.junit.Test;
import com.raytheon.edex.esb.Headers;
import com.raytheon.edex.exception.DecoderException;
import com.raytheon.edex.plugin.redbook.common.RedbookRecord;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.localization.PathManagerFactoryTest;
import com.raytheon.uf.common.util.FileUtil;
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
/**
* Regression Test RedbookRecords decoded by the RedbookDecoder against known
* decoder output.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Apr 22, 2013 1958 bgonzale Initial creation
*
* </pre>
*
* @author bgonzale
* @version 1.0
*/
public class RedbookDecoderTest {
final static String DataDir = "./data/Redbook";
private class RedbookTest {
public final byte[] rawMessage;
public final Headers headers;
public final RedbookRecord result;
public final String id;
public RedbookTest(byte[] rawMessage, Headers headers,
RedbookRecord result, byte[] redbookData, String id) {
super();
this.rawMessage = rawMessage;
this.headers = headers;
this.result = result;
if (result != null && redbookData != null) {
this.result.setRedBookData(redbookData);
}
this.id = id;
}
public boolean hasResults() {
return result != null;
}
}
private static class RedbookInput {
private static final String DOT = ".";
private static final String HEADERS_EXT = ".Headers";
private static final String RESULT_EXT = ".Result";
private static final String REDBOOKDATA_EXT = ".RedbookData";
private static FilenameFilter inputExtensionFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".Input");
}
};
public final File inputFile;
public final File headersFile;
public final File resultFile;
public final File resultRedbookDataFile;
public final String id;
public RedbookInput(File inputFile) {
String inputPath = inputFile.getAbsolutePath();
int indexOfExtension = inputPath.lastIndexOf(DOT);
String nameNoExtension = inputPath.substring(0, indexOfExtension);
this.inputFile = inputFile;
this.headersFile = new File(nameNoExtension + HEADERS_EXT);
this.resultFile = new File(nameNoExtension + RESULT_EXT);
this.resultRedbookDataFile = new File(nameNoExtension
+ REDBOOKDATA_EXT);
this.id = nameNoExtension.substring(nameNoExtension
.lastIndexOf(File.separator) + 1);
}
public boolean hasHeaders() {
return this.headersFile != null && this.headersFile.exists();
}
public boolean hasResult() {
return this.resultFile != null && this.resultFile.exists();
}
public static RedbookInput[] getInputs() {
File dataDir = new File(DataDir);
File[] inputFiles = dataDir.listFiles(inputExtensionFilter);
RedbookInput[] inputs = new RedbookInput[inputFiles.length];
int index = -1;
for (File inputFile : inputFiles) {
RedbookInput input = new RedbookInput(inputFile);
inputs[++index] = input;
}
return inputs;
}
}
private Collection<RedbookTest> tests;
public RedbookDecoderTest() throws IOException {
PathManagerFactoryTest.initLocalization();
tests = new ArrayList<RedbookDecoderTest.RedbookTest>();
// load test byte arrays, test header data, and result objects.
InputStream inStrm = null;
ByteArrayBuffer outStrm = null;
for (RedbookInput redbookInput : RedbookInput.getInputs()) {
byte[] rawMessage = null;
Headers headers = null;
RedbookRecord result = null;
byte[] redbookData = null;
// read rawMessage
rawMessage = FileUtil.file2bytes(redbookInput.inputFile);
// read header data
if (redbookInput.hasHeaders()) {
headers = new Headers();
BufferedReader reader = null;
try {
inStrm = new FileInputStream(redbookInput.headersFile);
reader = new BufferedReader(new InputStreamReader(inStrm));
String headerName = null;
String value = null;
while ((headerName = reader.readLine()) != null) {
value = reader.readLine();
if (value != null) {
headers.put(headerName, value);
}
}
} finally {
try {
if (inStrm != null) {
inStrm.close();
inStrm = null;
}
} finally {
if (reader != null) {
reader.close();
reader = null;
}
}
}
}
// read result
if (redbookInput.hasResult()) {
try {
JAXBContext con = JAXBContext
.newInstance(RedbookRecord.class);
Unmarshaller unmarshaller = con.createUnmarshaller();
result = (RedbookRecord) unmarshaller
.unmarshal(redbookInput.resultFile);
fixTimeObs(result);
} catch (Exception e) {
e.printStackTrace();
}
}
// read result redbook data
try {
redbookData = FileUtil
.file2bytes(redbookInput.resultRedbookDataFile);
} catch (FileNotFoundException e) {
// if a result file is not found then the input file does not
// produce a result.
redbookData = null;
}
RedbookTest test = new RedbookTest(rawMessage, headers, result,
redbookData,
redbookInput.id);
tests.add(test);
}
}
private static void fixTimeObs(RedbookRecord record) {
if (record != null) {
Calendar cal = record.getTimeObs();
Calendar newCal = GregorianCalendar.getInstance(TimeZone
.getTimeZone("Zulu"));
newCal.setTimeInMillis(cal.getTimeInMillis());
record.setTimeObs(newCal);
}
}
/**
* Test method for
* {@link com.raytheon.edex.plugin.redbook.RedbookDecoder#decode(byte[], com.raytheon.edex.esb.Headers)}
* .
*
* @throws DecoderException
*/
@Test
public void testDecode() throws DecoderException {
RedbookDecoder decoder = new RedbookDecoder(this.getClass().getName());
for (RedbookTest test : tests) {
PluginDataObject[] result = decoder.decode(test.rawMessage,
test.headers);
int expectedNumberOfResults = test.hasResults() ? 1 : 0;
assertEquals(test.id
+ " Failure, incorrect number of results returned for "
+ test.id, expectedNumberOfResults, result.length);
RedbookRecord expectedResult = (RedbookRecord) (test.hasResults() ? test.result
: null);
RedbookRecord actualResult = (RedbookRecord) (result.length > 0 ? result[0]
: null);
// insert times have to match to perform comparison
if (expectedResult != null && actualResult != null) {
actualResult.setInsertTime(expectedResult.getInsertTime());
}
assertEquals(
test.id
+ " Failure, decoder output does not match regression test value for "
+ test.id, expectedResult, actualResult);
}
}
}

View file

@ -55,6 +55,7 @@ public class TestJaxbableClassesLocator implements IJaxbableClassesLocator {
private static final List JAXB_CLASSES;
static {
Class<?>[] array = new Class<?>[] {
com.raytheon.edex.plugin.redbook.decoder.RedbookFcstMap.class,
com.raytheon.uf.common.datadelivery.registry.AdhocSubscription.class,
com.raytheon.uf.common.datadelivery.registry.Connection.class,
com.raytheon.uf.common.datadelivery.registry.Coverage.class,