Use of "RecordCondition.ExcludeIfMatchRegex" - filehelpers

Library version: v2.0.0.0
I would like to use ExcludeIfMatchRegex to exclude certain lines in the input file.
I have tested next code but the system is displaying the usual message error Object reference not set to an instance of an object.
If I remove the line containing "ConditionalRecord", the system reads the file and returns the usual validation messages.
using FileHelpers;
using System;
[IgnoreEmptyLines()]
[ConitionalRecord(RecordCondition.ExcludeIfMatchRegex, "[0-9 A-Za-z.,]{1}S[0-9 A-Za-z.,]{10}")]
[FixedLengthRecord(FixedMode.ExactLength)]
public sealed class PurchaseOrder : INotifyRead
{
[FieldFixedLength(1)]
[FieldTrim(TrimMode.Both)]
public string C;
[FieldFixedLength(1)]
[FieldTrim(TrimMode.Both)]
public string A;
[FieldFixedLength(10)]
[FieldTrim(TrimMode.Both)]
public string item;
public void AfterRead(EngineBase engine, string line)
{
// not exist the property "SkipThisRecord"??
}
}

Looks like a small bug in the 2.0.0.0 library.
When the FileHelpers engine reads a file but ALL lines are excluded AND the class is decorated with INotifyRead it throws the Object Reference error.
However you can work around it by using the AfterReadRecord event instead.
[IgnoreEmptyLines()]
[ConditionalRecord(RecordCondition.ExcludeIfMatchRegex, "[0-9 A-Za-z.,]{1}S[0-9 A-Za-z.,]{10}")]
[FixedLengthRecord(FixedMode.ExactLength)]
public sealed class PurchaseOrder
{
[FieldFixedLength(1)]
[FieldTrim(TrimMode.Both)]
public string C;
[FieldFixedLength(1)]
[FieldTrim(TrimMode.Both)]
public string A;
[FieldFixedLength(10)]
[FieldTrim(TrimMode.Both)]
public string item;
}
internal class Program
{
static void Main(string[] args)
{
FileHelperEngine engine = new FileHelperEngine(typeof(PurchaseOrder));
// use the AfterReadRecord event instead of the INotifyRead interface
engine.AfterReadRecord += Engine_AfterReadRecord;
// The record will be skipped because of the Regex
var records = engine.ReadString("0S0123456789");
Debug.Assert(records.Length == 0);
Console.Write("All OK. No records were imported.");
Console.ReadKey();
}
// Define the event here instead of in your FileHelpers class
private static void Engine_AfterReadRecord(EngineBase engine, AfterReadRecordEventArgs e)
{
// not exist the property "SkipThisRecord"??
}

Related

How to see arguments when creating a new class?

When creating a new class or method I used to be able to see the parameters needed. But, now they don't come up anymore. How do I view parameters when creating a class?
Running the latest windows version.
public class Main {
public static void main(String args[]) {
Case theCase = new Case("Default", "Corsair", "500W");
}
}
public class Case {
private String model;
private String manufacturer;
private String powerSupply;
public Case(String model, String manufacturer, String powerSupply,) {
this.model = model;
this.manufacturer = manufacturer;
this.powerSupply = powerSupply;
}
public void pressPowerButton() {
System.out.println("Power button pressed");
}
public String getModel() {
return model;
}
public String getManufacturer() {
return manufacturer;
}
public String getPowerSupply() {
return powerSupply;
}
}
When making theCase I can't see what my parameters are and have to move to the "Case" class back and forth
You can explicitly call Parameter Info action which is usually mapped to Ctrl/(Cmd) - p.
Nevermind in order to see the parameters as you type you must type them while in the editor without moving your cursor.

Protobuf-net / NetCore2: Deserialization ignores annotated private fields

Edit: The problem was with Nancy. Protobuf-net (de)serializes marked private fields just fine.
I am running a NetCore 2.0 unit test project. Protobuf-net appears to be ignored private fields even though the have the [ProtoMember] attribute.
[ProtoContract]
internal class Model
{
[ProtoMember(1)]
public int Example { get; private set; } // Works
[ProtoMember(2)]
private List<int> _a; // Not deserialized unless made public
public IEnumerable<int> A => this._a;
public Model(int example, IEnumerable<int> a)
{
this.Example = example;
this._a = a.ToList(); // Copy prevents mutation
}
private Model() // For deserialization
{
}
}
I have used a public IEnumerable<int> to avoid mutability and hide implementation details. It is backed by a private List<int> to allow serialization. However, protobuf-net will only deserialize the field if I make it public. The serialization, on the other hand, will actually include the data even if the field is private.
Is this intended behavior? Is there are a clean way to make protobuf-net honor the marked private field when deserializing?
P.S. The same behavior is seen for non-collection members, but I have demonstrated with IEnumerable/List because it shows the reason for this approach.
The following works identically (apart from the first line of the output) when targetting netcoreapp2.0 or net45. I'd be happy to help, but I'd need to see an example that fails. I'm using:
<PackageReference Include="protobuf-net" Version="2.3.6" />
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using ProtoBuf;
[ProtoContract]
internal class Model
{
[ProtoMember(1)]
public int Example { get; private set; } // Works
[ProtoMember(2)]
private List<int> _a; // Not deserialized unless made public
public IEnumerable<int> A => this._a;
public Model(int example, IEnumerable<int> a)
{
this.Example = example;
this._a = a.ToList(); // Copy prevents mutation
}
private Model() // For deserialization
{
}
}
static class Program
{
static void Main()
{
#if NETCOREAPP2_0
Console.WriteLine(".NET Core 2.0");
#elif NET45
Console.WriteLine(".NET 4.5");
#endif
var obj = new Model(123, new int[] { 4, 5, 6 });
var clone = Serializer.DeepClone(obj);
Console.WriteLine(clone.Example);
foreach (var val in clone.A)
{
Console.WriteLine(val);
}
}
}

Morphia Interface for List of enum does not work (unmarshalling)

I have the following interface
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "className")
public interface InfoChartInformation {
public String name();
}
And the following implementation (enum):
public class InfoChartSummary {
public static enum Immobilien implements InfoChartInformation {
CITY, CONSTRUCTION_DATE;
}
public static enum Cars implements InfoChartInformation {
POWER, MILEAGE;
}
}
Then I use all of It in the following entity:
#Entity(noClassnameStored = true)
#Converters(InfoChartInformationMorphiaConverter.class)
public class TestEntity{
#Id
public ObjectId id;
#Embedded
public List<InfoChartInformation> order;
}
Jackson, in order to detect the type on the unmarshalling time, will add to every enum on the list the className.
I thought morphia would do the same, but there's no field className in the List of enum and the unmarshalling cannot be done correctly: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: java.lang.String cannot be cast to com.mongodb
.DBObject
I guess the correct behavior should be to save all the enum route (package+name), not only the enum name. At least in that way the unmarshalling could be performed. There's a way morphia supports that by default or I need to create my own converter (similar to this) ?
I tried creating a Custom Converter:
public class InfoChartInformationMorphiaConverter extends TypeConverter{
public InfoChartInformationMorphiaConverter() {
super(InfoChartInformation.class);
}
#Override
public Object decode(Class targetClass, Object fromDBObject, MappedField optionalExtraInfo) {
if (fromDBObject == null) {
return null;
}
String clazz = fromDBObject.toString().substring(0, fromDBObject.toString().lastIndexOf("."));
String value = fromDBObject.toString().substring(fromDBObject.toString().lastIndexOf(".") + 1);
try {
return Enum.valueOf((Class)Class.forName(clazz), value);
} catch (ClassNotFoundException e) {
return null;
}
}
#Override
public Object encode(final Object value, final MappedField optionalExtraInfo) {
return value.getClass().getName() + "." + ((InfoChartInformation) value).name();
}
}
Then, I added the converter information to morphia morphia.getMapper().getConverters().addConverter(new InfoChartInformationMorphiaConverter());.
However, when serializing (or marshalling) the object to save it into the database, the custom converter is ignored and the Enum is saved using the default Morphia converter (only the enum name).
If I use in the TestEntity class only an attribute InfoChartInformation; instead of the List<>InfoChartInformation>, my customer converter will work. However I need support for List
Use:
public class InfoChartInformationMorphiaConverter extends TypeConverter implements SimpleValueConverter
It is a marker interface required to make your Convertor work.

PIG Algebraic UDF with arguments : Combiner optimizer error

I'm trying to build a Pig UDF that performs some aggregation on a variable of type double. To do so, I built an algebraic UDF called Aggreg. It is called in the following script:
REGISTER 'Test.jar';
DEFINE Aggreg com.pig.test.Agreg();
records = LOAD '/tmp/Test.csv' USING PigStorage(',') AS (v1:chararray, v2:double);
grouped_rec = GROUP records ALL;
test = FOREACH grouped_rec GENERATE Aggreg(records.v2) AS val;
DUMP test;
This works fine as it is. Then, I wanted to use the arguments for this UDF so I added a public constructor with one String argument.
I just changed the DEFINE statement in the previous script but haven't yet used the argument in the UDF Java code:
DEFINE Aggreg com.pig.test.Agreg('Test');
And now I get the following error:
ERROR org.apache.pig.tools.grunt.Grunt - ERROR 2018: Internal error. Unable to introduce the combiner for optimization.
Any ideas where this could come from?
Using Algebraic interface, you must implement two constructors in classes Initial, Intermed and Final, the default constructor and constructor with the parameter you use.
static public class Initial extends EvalFunc<Tuple> {
public Initial(){}
public Initial(String str){Aggreg.string=trs;}
#Override
public Tuple exec(Tuple input) throws IOException {
...
}
}
static public class Intermed extends EvalFunc<Tuple> {
public Intermed(){}
public Intermed(String str){Aggreg.string=trs;}
#Override
public Tuple exec(Tuple input) throws IOException {
...
}
}
static public class Final extends EvalFunc<Tuple> {
public Final(){}
public Final(String str){Aggreg.string=trs;}
#Override
public Tuple exec(Tuple input) throws IOException {
...
}
}
public String getInitial() {
return Initial.class.getName();
}
public String getIntermed() {
return Intermed.class.getName();
}
public String getFinal() {
return Final.class.getName();
}

In OOP reading from text file should be a Independent class method?

I have a class that only have main which read in some txt and do the algorithms.
my class is look like:
class doThejob{
public static void main(String args[]){
//*****start part A******
//do the reading from text file, and tokenize it
// process into the form I need,
//about 10-30 lines of codes
//******End of part A*****
//then run the algorithms
algorithm alg=new aglorithm();
Object output = alg.x(input);
//****Part B**** output to txt, about 10~40 lines
}
}
class algorithm{
private void a(Object x){
//do something
return (Object)result;
}
}
Can anyone tell me should I extract those part A and part B to a new class ,and then setup them as a public method .like below
class Io{
public Object readFromTxt(String path){
}
public void outputToTxt(String path){
}
}
And if I setup them , and then use it like below, is that more OOP?
class doThejob{
public static void main(String args[]){
Io dataProcess= new Io();
Object input = dataProcess.readFromTxt(args[0]);
algorithm alg=new aglorithm();
Object output =alg.x(input);
dataProcess.readFromTxt(args[1],output);
}
}
class algorithm{
private Object a(Object x){
//do something
}
}
Do it the way you fill is more readable.
Separating this in another class is according to the Single Responsability Principle. It will help making the code more readable and easy to change later on.
If you want to expand more on this, you could create an interface (eg.: IIO) for input and output. This way you can implement this interface in the IO class, renaming it to FileIO. Anytime you want to create another form of IO, like database access, you just have to create a DatabaseIO class that implements this interface and change the instance in the main method for this new type:
public interface IIO
{
string Read();
void Write(string text);
}
public class FileIO : IIO
{
string path;
public FileIO(string filePath)
{
path = filePath;
}
public string Read()
{
// read from file and return contents
}
public void Write(string text)
{
// write to file
}
}
public class SqlServerIO : IIO
{
SqlConnection conn;
public SqlServerIO(string connectionStringName)
{
// create the connection
}
public string Read()
{
// read from database
}
public void Write(string text)
{
// write to database
}
}
Extracting interfaces makes the code more maintenable by alowing to switch implementations anytime without messing with working code. It also facilitates unit testing.