Get entity object's property names excluding entitycollection and entityreference - c#-4.0

I am working on a method that compares two objects using reflection. The object types are objects created from entity framework. When I use GetProperties() I am getting EntityCollection and EntityReference properties. I only want the properties that belong to the object and not any associated properties or references from foreign keys.
I've tried the following How to get all names of properties in an Entity?.
I thought about passing an array of properties to compare but I don't want to have to type them in for each object type. I am open to some suggestions even those that don't use reflection.
public bool CompareEntities<T>(T oldEntity, T newEntity)
{
bool same = true;
PropertyInfo[] properties = oldEntity.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
var oldValue = property.GetValue(oldEntity, null);
var newValue = property.GetValue(newEntity, null);
if (oldValue != null && newValue != null)
{
if (!oldValue.Equals(newValue))
{
same = false;
break;
}
}
else if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null))
{
same = false;
break;
}
}
return same;
}

Using the suggestions from #Eranga and https://stackoverflow.com/a/5381986/1129035 I was able to come up with a workable solution.
Since some of the properties in the root object are a GenericType there needs to be two different if statements. Only if the current property is an EntityCollection skip over it.
public bool CompareEntities<T>(T oldEntity, T newEntity)
{
bool same = true;
PropertyInfo[] properties = oldEntity.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
.Where(pi => !(pi.PropertyType.IsSubclassOf(typeof(EntityObject)))
&& !(pi.PropertyType.IsSubclassOf(typeof(EntityReference)))
).ToArray();
foreach (PropertyInfo property in properties)
{
if (property.PropertyType.IsGenericType)
{
if (property.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection<>))
{
continue;
}
}
var oldValue = property.GetValue(oldEntity, null);
var newValue = property.GetValue(newEntity, null);
if (oldValue != null && newValue != null)
{
if (!oldValue.Equals(newValue))
{
same = false;
break;
}
}
else if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null))
{
same = false;
break;
}
}
return same;
}

Try filtering out EntityObject type and EntityCollection properties.
var properties = oldEntity.GetType().GetProperties().
Where(pi => !(pi.PropertyType.IsSubclassOf(typeof(EntityObject))
|| pi.PropertyType.IsSubclassOf(typeof(EntityCollection));

make it easy for yourself and do this instead
PropertyInfo[] properties = oldEntity.GetType().GetProperties(pi=> pi.PropertyType.NameSpace=="System").ToArray();

Related

Changing the Default Option for Column Filters

Is it possible to change the default option all column filters? I'm pretty sure I can accomplish this with some JavaScript, but I'd like to know if there's any way within the Acumatica framework to change this.
The answer will be no. The filter is inside the PX.Web.UI.dll in the PXGridFilter class which is an internal class. The property that you are interested in is the Condition.
The value is set inside one of the private methods of the PXGrid class. The code of the method is below:
private IEnumerable<PXGridFilter> ab()
{
List<PXGridFilter> list = new List<PXGridFilter>();
if (this.FilterID != null)
{
Guid? filterID = this.FilterID;
Guid guid = PXGrid.k;
if (filterID == null || (filterID != null && filterID.GetValueOrDefault() != guid))
{
using (IEnumerator<PXResult<FilterRow>> enumerator = PXSelectBase<FilterRow, PXSelect<FilterRow, Where<FilterRow.filterID, Equal<Required<FilterRow.filterID>>, And<FilterRow.isUsed, Equal<True>>>>.Config>.Select(this.DataGraph, new object[]
{
this.FilterID.Value
}).GetEnumerator())
{
while (enumerator.MoveNext())
{
FilterRow row = enumerator.Current;
string dataField = row.DataField;
PXCache pxcache = PXFilterDetailView.TargetCache(this.DataGraph, new Guid?(this.FilterID.Value), ref dataField);
if (this.Columns[row.DataField] != null)
{
List<PXGridFilter> list2 = list;
int valueOrDefault = row.OpenBrackets.GetValueOrDefault();
string dataField2 = row.DataField;
string dataField3 = row.DataField;
int value = (int)row.Condition.Value;
object value2 = pxcache.ValueFromString(dataField, row.ValueSt);
string valueText = row.ValueSt.With((string _) => this.Columns[row.DataField].FormatValue(_));
object value3 = pxcache.ValueFromString(dataField, row.ValueSt2);
string value2Text = row.ValueSt2.With((string _) => this.Columns[row.DataField].FormatValue(_));
int valueOrDefault2 = row.CloseBrackets.GetValueOrDefault();
int? #operator = row.Operator;
int num = 1;
list2.Add(new PXGridFilter(valueOrDefault, dataField2, dataField3, value, value2, valueText, value3, value2Text, valueOrDefault2, #operator.GetValueOrDefault() == num & #operator != null));
}
}
return list;
}
}
}
if (this.FilterRows != null && this.FilterRows.Count > 0)
{
for (int i = 0; i < this.FilterRows.Count; i++)
{
PXFilterRow row = this.FilterRows[i];
list.Add(new PXGridFilter(row.OpenBrackets, row.DataField, row.DataField, (int)row.Condition, row.Value, row.Value.With(delegate(object _)
{
if (this.Columns[row.DataField] == null)
{
return _.ToString();
}
return this.Columns[row.DataField].FormatValue(_);
}), row.Value2, row.Value2.With(delegate(object _)
{
if (this.Columns[row.DataField] == null)
{
return _.ToString();
}
return this.Columns[row.DataField].FormatValue(_);
}), row.CloseBrackets, row.OrOperator));
}
}
return list;
}
UPDATE
The below JS code allows you to change the condition of the last set filter:
px_all.ctl00_phG_grid_fd.show();
px_all.ctl00_phG_grid_fd_cond.items.items[7].setChecked(true);
px_all.ctl00_phG_grid_fd_ok.element.click();
px_all.ctl00_phG_grid_fd_cond.items.items[7].value "EQ"
px_all.ctl00_phG_grid_fd_cond.items.items[8].value "NE"
px_all.ctl00_phG_grid_fd_cond.items.items[9].value "GT"
px_all.ctl00_phG_grid_fd_cond.items.items[13].value "LIKE"
px_all.ctl00_phG_grid_fd_cond.items.items[14].value "LLIKE"
px_all.ctl00_phG_grid_fd_cond.items.items[15].value "RLIKE"
px_all.ctl00_phG_grid_fd_cond.items.items[16].value "NOTLIKE"
px_all.ctl00_phG_grid_fd_cond.items.items[18].value "ISNULL"
px_all.ctl00_phG_grid_fd_cond.items.items[19].value "ISNOTNULL"

Acumatica Pagination Implementation for Processing Screen does not returns all applicable values

I have tried to implement pagination for my custom processing screen but not getting all the required values in the grid.
If I am using below code, where I did not implemented pagination and directly using BQL in the foreach() loop for getting the records, I am getting all the applicable values.
public PXCancel<KNPIPaymentFilter> cancel;
public PXFilter<KNPIPaymentFilter> KNPIFilter;
[PXFilterable]
public PXFilteredProcessing<SOOrder, KNPIPaymentFilter> KNPIProcessOrders;
protected bool _PayMethodChanged = false;
protected bool _PayActionChanged = false;
public virtual void KNPIPaymentFilter_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
{
_PayMethodChanged = !sender.ObjectsEqual<KNPIPaymentFilter.paymentMethodID>(e.Row, e.OldRow);
_PayActionChanged = !sender.ObjectsEqual<KNPIPaymentFilter.payPalInvAction>(e.Row, e.OldRow);
}
public IEnumerable kNPIProcessOrders()
{
if (_PayMethodChanged || _PayActionChanged)
KNPIProcessOrders.Cache.Clear();
KNPIPaymentFilter filter = PXCache<KNPIPaymentFilter>.CreateCopy(KNPIFilter.Current);
if (filter.PayPalInvAction == KNPIConstants.SL)
yield break;
foreach (SOOrder order in PXSelect<SOOrder, Where<SOOrder.orderType, Equal<SOOrderTypeConstants.salesOrder>, And<SOOrder.paymentMethodID, Equal<Required<KNPIPaymentFilter.paymentMethodID>>,
And<SOOrder.status, NotEqual<SOOrderStatus.completed>>>>>.Select(this, this.KNPIFilter.Current.PaymentMethodID))
{
KNPIPayments PayPalPayment = new PXSelect<KNPIPayments, Where<KNPIPayments.acmOrderNbr, Equal<Required<KNPIPayments.acmOrderNbr>>,
And<KNPIPayments.acmOrderType, Equal<Required<KNPIPayments.acmOrderType>>>>, OrderBy<Desc<KNPIPayments.lineNbr>>>
(this).SelectWindowed(0, 1, order.OrderNbr, order.OrderType);
if (filter.PayPalInvAction == KNPIConstants.RE)
{
if (PayPalPayment == null || (PayPalPayment != null && PayPalPayment.PayPalInvoiceStatus == KNPIConstants.CANCELLED))
yield return order;
}
else if (filter.PayPalInvAction == KNPIConstants.CH)
{
if (PayPalPayment != null && PayPalPayment.PayPalInvoiceStatus == KNPIConstants.SENT)
yield return order;
}
}
KNPIProcessOrders.Cache.IsDirty = false;
}
But when I am implementing pagination logic like below, I am not getting any of the record in the grid. I have debugged the code and found out in the list object it is loading only 19 records initially but after that other records are not at all loading in the object.
public PXCancel<KNPIPaymentFilter> cancel;
public PXFilter<KNPIPaymentFilter> KNPIFilter;
[PXFilterable]
public PXFilteredProcessing<SOOrder, KNPIPaymentFilter> KNPIProcessOrders;
protected bool _PayMethodChanged = false;
protected bool _PayActionChanged = false;
public virtual void KNPIPaymentFilter_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
{
_PayMethodChanged = !sender.ObjectsEqual<KNPIPaymentFilter.paymentMethodID>(e.Row, e.OldRow);
_PayActionChanged = !sender.ObjectsEqual<KNPIPaymentFilter.payPalInvAction>(e.Row, e.OldRow);
}
public IEnumerable kNPIProcessOrders()
{
if (_PayMethodChanged || _PayActionChanged)
KNPIProcessOrders.Cache.Clear();
KNPIPaymentFilter filter = PXCache<KNPIPaymentFilter>.CreateCopy(KNPIFilter.Current);
if (filter.PayPalInvAction == KNPIConstants.SL)
yield break;
PXSelectBase<SOOrder> cmd = new PXSelect<SOOrder, Where<SOOrder.orderType, Equal<SOOrderTypeConstants.salesOrder>, And<SOOrder.status, NotEqual<SOOrderStatus.completed>,
And<SOOrder.paymentMethodID, Equal<Optional<KNPIPaymentFilter.paymentMethodID>>>>>>(this);
int startRow = PXView.StartRow;
int totalRows = 0;
List<object> list = cmd.View.Select(new[] { KNPIFilter.Current }, null, PXView.Searches,
PXView.SortColumns, PXView.Descendings, PXView.Filters, ref startRow, PXView.MaximumRows, ref totalRows);
foreach (SOOrder order in list)
{
KNPIPayments PayPalPayment = new PXSelect<KNPIPayments, Where<KNPIPayments.acmOrderNbr, Equal<Required<KNPIPayments.acmOrderNbr>>,
And<KNPIPayments.acmOrderType, Equal<Required<KNPIPayments.acmOrderType>>>>, OrderBy<Desc<KNPIPayments.lineNbr>>>
(this).SelectWindowed(0, 1, order.OrderNbr, order.OrderType);
if (this.KNPIFilter.Current.PayPalInvAction == KNPIConstants.RE)
{
if (PayPalPayment == null || (PayPalPayment != null && PayPalPayment.PayPalInvoiceStatus == KNPIConstants.CANCELLED))
yield return order;
}
else if (this.KNPIFilter.Current.PayPalInvAction == KNPIConstants.CH)
{
if (PayPalPayment != null && PayPalPayment.PayPalInvoiceStatus == KNPIConstants.SENT)
yield return order;
}
}
PXView.StartRow = 0;
KNPIProcessOrders.Cache.IsDirty = false;
}
Can someone please help me out, as what I am doing wrong or what I am missing here.

What's the event for changing Severity on screen Case (ScreenID: CR306000)?

After I customized the code below and I want to update SLA by AssignDateTime. But with the Severity changed then my SLA has changed to get datetime from createdDateTime also. I think it should have other event that need to customize.
protected virtual void CRCase_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e, PXRowUpdated InvokeBaseHandler)
{
if (InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var row = e.Row as CRCase;
var oldRow = e.OldRow as CRCase;
CRCaseExt rowExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);
if (row == null || oldRow == null) return;
if (row.OwnerID == null)
{
row.AssignDate = null;
row.SLAETA = null;
}
else if (oldRow.OwnerID == null)
{
row.AssignDate = PXTimeZoneInfo.Now;
if (row == null || row.AssignDate == null) return;
if (row.ClassID != null && row.Severity != null)
{
var severity = (CRClassSeverityTime)PXSelect<CRClassSeverityTime,
Where<CRClassSeverityTime.caseClassID, Equal<Required<CRClassSeverityTime.caseClassID>>,
And<CRClassSeverityTime.severity, Equal<Required<CRClassSeverityTime.severity>>>>>
.Select(Base, row.ClassID, row.Severity);
if (severity != null && severity.TimeReaction != null)
{
row.SLAETA = ((DateTime)row.AssignDate).AddMinutes((int)severity.TimeReaction);
}
}
if (row.Severity != null && row.ContractID != null)
{
var template = (Contract)PXSelect<Contract, Where<Contract.contractID, Equal<Required<CRCase.contractID>>>>.Select(Base, row.ContractID);
if (template == null) return;
var sla = (ContractSLAMapping)PXSelect<ContractSLAMapping,
Where<ContractSLAMapping.severity, Equal<Required<CRCase.severity>>,
And<ContractSLAMapping.contractID, Equal<Required<CRCase.contractID>>>>>
.Select(Base, row.Severity, template.TemplateID);
if (sla != null && sla.Period != null)
{
row.SLAETA = ((DateTime)row.AssignDate).AddMinutes((int)sla.Period);
}
}
}
}
SLAETA field is decorated with PXFormulaAttribute to raise FieldDefaulting event every time change is made to one of the following fields:
CRCase.contractID
CRCase.severity
CRCase.caseClassID
public partial class CRCase : IBqlTable, IAssign, IAttributeSupport, IPXSelectable
{
...
#region SLAETA
public abstract class sLAETA : IBqlField { }
[PXDBDate(PreserveTime = true, DisplayMask = "g")]
[PXUIField(DisplayName = "SLA")]
[PXFormula(typeof(Default<CRCase.contractID, CRCase.severity, CRCase.caseClassID>))]
public virtual DateTime? SLAETA { get; set; }
#endregion
...
}
It’s a way better to only customize CRCase_SLAETA_FieldDefaulting handler in the CRCaseMaint BLC extension instead of implementing CRCase_RowUpdated:
public class CRCaseMaint : PXGraph<CRCaseMaint, CRCase>
{
...
protected virtual void CRCase_SLAETA_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{
CRCase row = e.Row as CRCase;
if (row == null || row.CreatedDateTime == null) return;
if (row.ClassID != null && row.Severity != null)
{
var severity = (CRClassSeverityTime)PXSelect<CRClassSeverityTime,
Where<CRClassSeverityTime.caseClassID, Equal<Required<CRClassSeverityTime.caseClassID>>,
And<CRClassSeverityTime.severity, Equal<Required<CRClassSeverityTime.severity>>>>>.
Select(this, row.ClassID, row.Severity);
if (severity != null && severity.TimeReaction != null)
{
e.NewValue = ((DateTime)row.CreatedDateTime).AddMinutes((int)severity.TimeReaction);
e.Cancel = true;
}
}
if (row.Severity != null && row.ContractID != null)
{
var template = (Contract)PXSelect<Contract, Where<Contract.contractID, Equal<Required<CRCase.contractID>>>>.Select(this, row.ContractID);
if (template == null) return;
var sla = (ContractSLAMapping)PXSelect<ContractSLAMapping,
Where<ContractSLAMapping.severity, Equal<Required<CRCase.severity>>,
And<ContractSLAMapping.contractID, Equal<Required<CRCase.contractID>>>>>.
Select(this, row.Severity, template.TemplateID);
if (sla != null && sla.Period != null)
{
e.NewValue = ((DateTime)row.CreatedDateTime).AddMinutes((int)sla.Period);
e.Cancel = true;
}
}
}
...
}
You can either use the FieldUpdated Event or in the row updated event you can look for the change of your field.
Eg: row.Severity != oldRow.Severity

Can we save jaxb context bindings to oxm metadata file?

We have the opportunity to init jaxb context from external oxm file
Map<String, Object> props = new HashMap<String, Object>(1);
props.put(JAXBContextProperties.OXM_METADATA_SOURCE, "oxm.xml");
JAXBContext jc = JAXBContextFactory.createContext(new Class[0], props, <ClassLoader>);
Can we safe current jaxb context xml bindings to xml? From context inited from jaxb annotated classes (I have jaxb.properties)
JAXBContext jc = JAXBContext.newInstance(new Class[]{...});
Like I save generated schema to file
jc.generateSchema(new SchemaOutputResolver(){...});
I need to write oxm file of my schema with only difference in date/time representation.
I create function to create oxm from package. It is not complete, but do everything that I needed, and good as starting point...
public static void createOXM(Package pack, String filename)
throws Exception
{
/*
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="eclipselink_oxm_2_4.xsd"
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" package-name="<name>"
xml-mapping-metadata-complete="true" xml-accessor-type="NONE" xml-accessor-order="UNDEFINED">
*/
org.eclipse.persistence.jaxb.xmlmodel.XmlBindings bindings =
new org.eclipse.persistence.jaxb.xmlmodel.XmlBindings();
bindings.setPackageName(pack.getName());
bindings.setXmlMappingMetadataComplete(true);
bindings.setXmlAccessorType(org.eclipse.persistence.jaxb.xmlmodel.XmlAccessType.NONE);
bindings.setXmlAccessorOrder(org.eclipse.persistence.jaxb.xmlmodel.XmlAccessOrder.UNDEFINED);
List<Class<?>> classes = getClassesForPackage(pack);
for (Class<?> cls: classes)
{
int clsMod = cls.getModifiers();
String clsName = cls.getName().replaceAll("[^\\.]+\\.", "");
if (cls.isAnonymousClass() || !Modifier.isPublic(clsMod)) // Class$1 etc...
continue;
if (cls.getAnnotation(XmlTransient.class) != null)
continue;
org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.JavaTypes javaTypes = bindings.getJavaTypes();
if (javaTypes == null)
{
javaTypes = new org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.JavaTypes();
bindings.setJavaTypes(javaTypes);
}
org.eclipse.persistence.jaxb.xmlmodel.JavaType javaType = new org.eclipse.persistence.jaxb.xmlmodel.JavaType();
javaTypes.getJavaType().add(javaType);
javaType.setName(clsName);
XmlRootElement xmlRoot = cls.getAnnotation(XmlRootElement.class);
if (xmlRoot != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement root =
new org.eclipse.persistence.jaxb.xmlmodel.XmlRootElement();
javaType.setXmlRootElement(root);
if (!"##default".equals(xmlRoot.name()))
root.setName(xmlRoot.name());
if (!"##default".equals(xmlRoot.namespace()))
root.setNamespace(xmlRoot.namespace());
}
XmlType xmlType = cls.getAnnotation(XmlType.class);
if (xmlType != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlType type = new org.eclipse.persistence.jaxb.xmlmodel.XmlType();
javaType.setXmlType(type);
if (!"##default".equals(xmlType.name()))
type.setName(xmlType.name());
if (!"##default".equals(xmlType.namespace()))
type.setNamespace(xmlType.namespace());
String[] props = xmlType.propOrder();
if (props != null && props.length > 0)
{
for (String prop: props)
if (!prop.trim().isEmpty())
type.getPropOrder().add(prop.trim());
}
}
XmlAccessorType xmlAccType = cls.getAnnotation(XmlAccessorType.class);
if (xmlAccType != null)
{
String accType = xmlAccType.value().name();
javaType.setXmlAccessorType(org.eclipse.persistence.jaxb.xmlmodel.XmlAccessType.valueOf(accType));
}
if (cls.isEnum())
{
org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.XmlEnums enums = bindings.getXmlEnums();
if (enums == null)
{
enums = new org.eclipse.persistence.jaxb.xmlmodel.XmlBindings.XmlEnums();
bindings.setXmlEnums(enums);
}
org.eclipse.persistence.jaxb.xmlmodel.XmlEnum en = new org.eclipse.persistence.jaxb.xmlmodel.XmlEnum();
en.setJavaEnum(clsName);
enums.getXmlEnum().add(en);
XmlEnum xmlEnum = cls.getAnnotation(XmlEnum.class);
if (xmlEnum != null)
{
Class<?> xmlClass = xmlEnum.value();
if (xmlClass != String.class)
en.setValue(xmlClass.getName());
}
for (Field field: cls.getDeclaredFields())
if (field.isEnumConstant())
{
org.eclipse.persistence.jaxb.xmlmodel.XmlEnumValue value =
new org.eclipse.persistence.jaxb.xmlmodel.XmlEnumValue();
en.getXmlEnumValue().add(value);
value.setJavaEnumValue(field.getName());
value.setValue(field.getName());
XmlEnumValue enumValue = field.getAnnotation(XmlEnumValue.class);
if (enumValue != null)
value.setValue(enumValue.value());
}
continue;
}
Class clsSuper = cls.getSuperclass();
if (clsSuper.getPackage() == pack)
javaType.setSuperType(clsSuper.getName());
for (Field field: cls.getDeclaredFields())
{
org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes javaAttrs = javaType.getJavaAttributes();
if (javaAttrs == null)
{
javaAttrs = new org.eclipse.persistence.jaxb.xmlmodel.JavaType.JavaAttributes();
javaType.setJavaAttributes(javaAttrs);
}
XmlTransient xmlTrans = field.getAnnotation(XmlTransient.class);
if (xmlTrans != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlTransient attr =
new org.eclipse.persistence.jaxb.xmlmodel.XmlTransient();
attr.setJavaAttribute(field.getName());
javaAttrs.getJavaAttribute().add(new JAXBElement(new QName("", "xml-transient"), attr.getClass(), attr));
continue;
}
XmlValue xmlValue = field.getAnnotation(XmlValue.class);
if (xmlValue != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlValue attr = new org.eclipse.persistence.jaxb.xmlmodel.XmlValue();
attr.setJavaAttribute(field.getName());
javaAttrs.getJavaAttribute().add(new JAXBElement(new QName("", "xml-value"), attr.getClass(), attr));
continue;
}
XmlAttribute xmlAttr = field.getAnnotation(XmlAttribute.class);
if (xmlAttr != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlAttribute attr =
new org.eclipse.persistence.jaxb.xmlmodel.XmlAttribute();
attr.setJavaAttribute(field.getName());
if (!"##default".equals(xmlAttr.name()) && !field.getName().equals(xmlAttr.name()))
attr.setName(xmlAttr.name());
if (!"##default".equals(xmlAttr.namespace()))
attr.setNamespace(xmlAttr.namespace());
if (xmlAttr.required())
attr.setRequired(true);
XmlSchemaType xmlSchemaType = field.getAnnotation(XmlSchemaType.class);
if (xmlSchemaType != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlSchemaType schemaType =
new org.eclipse.persistence.jaxb.xmlmodel.XmlSchemaType();
attr.setXmlSchemaType(schemaType);
schemaType.setName(xmlSchemaType.name());
if (!"http://www.w3.org/2001/XMLSchema".equals(xmlSchemaType.namespace()))
schemaType.setName(xmlSchemaType.namespace());
if (xmlSchemaType.type() != XmlSchemaType.DEFAULT.class)
schemaType.setType(xmlSchemaType.type().getName());
}
XmlJavaTypeAdapter xmlJavaTypeAdapter = field.getAnnotation(XmlJavaTypeAdapter.class);
if (xmlJavaTypeAdapter != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter javaTypeAdapter =
new org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter();
attr.setXmlJavaTypeAdapter(javaTypeAdapter);
if (xmlJavaTypeAdapter.value() != null)
javaTypeAdapter.setValue(xmlJavaTypeAdapter.value().getName());
if (xmlJavaTypeAdapter.type() != XmlJavaTypeAdapter.DEFAULT.class)
javaTypeAdapter.setValue(xmlJavaTypeAdapter.type().getName());
}
javaAttrs.getJavaAttribute().add(new JAXBElement(new QName("", "xml-attribute"), attr.getClass(), attr));
continue;
}
XmlElement xmlElem = field.getAnnotation(XmlElement.class);
if (xmlElem != null && xmlAttr != null)
throw new RuntimeException("XmlAttribute and XmlElement can be both");
org.eclipse.persistence.jaxb.xmlmodel.XmlElement attr = new org.eclipse.persistence.jaxb.xmlmodel.XmlElement();
attr.setJavaAttribute(field.getName());
if (xmlElem != null)
{
if (!"##default".equals(xmlElem.name()) && !field.getName().equals(xmlElem.name()))
attr.setName(xmlElem.name());
if (!"##default".equals(xmlElem.namespace()))
attr.setNamespace(xmlElem.namespace());
if (!"\u0000".equals(xmlElem.defaultValue()))
attr.setDefaultValue(xmlElem.defaultValue());
if (xmlElem.required())
attr.setRequired(true);
if (xmlElem.nillable())
attr.setNillable(true);
}
XmlElementWrapper xmlWrapper = field.getAnnotation(XmlElementWrapper.class);
if (xmlWrapper != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlElementWrapper elemWrapper =
new org.eclipse.persistence.jaxb.xmlmodel.XmlElementWrapper();
attr.setXmlElementWrapper(elemWrapper);
if (!"##default".equals(xmlWrapper.name()))
elemWrapper.setName(xmlWrapper.name());
if (!"##default".equals(xmlWrapper.namespace()))
elemWrapper.setNamespace(xmlWrapper.namespace());
if (xmlWrapper.required())
elemWrapper.setRequired(true);
if (xmlWrapper.nillable())
elemWrapper.setNillable(true);
}
XmlSchemaType xmlSchemaType = field.getAnnotation(XmlSchemaType.class);
if (xmlSchemaType != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlSchemaType schemaType =
new org.eclipse.persistence.jaxb.xmlmodel.XmlSchemaType();
attr.setXmlSchemaType(schemaType);
schemaType.setName(xmlSchemaType.name());
if (!"http://www.w3.org/2001/XMLSchema".equals(xmlSchemaType.namespace()))
schemaType.setName(xmlSchemaType.namespace());
if (xmlSchemaType.type() != XmlSchemaType.DEFAULT.class)
schemaType.setType(xmlSchemaType.type().getName());
}
XmlJavaTypeAdapter xmlJavaTypeAdapter = field.getAnnotation(XmlJavaTypeAdapter.class);
if (xmlJavaTypeAdapter != null)
{
org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter javaTypeAdapter =
new org.eclipse.persistence.jaxb.xmlmodel.XmlJavaTypeAdapter();
attr.setXmlJavaTypeAdapter(javaTypeAdapter);
if (xmlJavaTypeAdapter.value() != null)
javaTypeAdapter.setValue(xmlJavaTypeAdapter.value().getName());
if (xmlJavaTypeAdapter.type() != XmlJavaTypeAdapter.DEFAULT.class)
javaTypeAdapter.setValue(xmlJavaTypeAdapter.type().getName());
}
javaAttrs.getJavaAttribute().add(new JAXBElement(new QName("", "xml-element"), attr.getClass(), attr));
}
}
JAXBContext jc = JAXBContext.newInstance(bindings.getClass());
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
m.setProperty(Marshaller.JAXB_FRAGMENT, false);
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(bindings, new File(filename));
}
Have fun!

Avoiding Multiple If's in c# - Best practise

Scenario:
Lets say we got to check for address lines. which includes addressline1, addressline2,Town,Country,Postcode
If any one of the property is entered, all other fields are mandatory.
If none of it is entered, the validation doesnt have to get trigged.
To achieve it, I ended up with two lines of If statement.
Like
if(AddressLine1 != null || AddressLine2 != null || Town != null || Country != null)
{
if(AddressLine1 != null && AddressLine2 != null && Town != null && Country != null) == false
{
return false;
}
}
Note: I am using c#. Are there any language constructs i can make use of.
private bool IsAddressValid(params string[] addressParts)
{
return addressParts.Any(p => p != null) ? addressParts.All(p => p != null) : true;
}
To be called like so:
var addressValid = IsAddressValid(AddressLine1, AddressLine2, Town, County);
Well, the null-coalescing operator can help with the first:
if (AddressLine1 ?? AddressLine2 ?? Town ?? Country != null)
{
if (AddressLine1 == null || AddressLine2 == null ||
Town == null || Country == null)
{
return false;
}
// Presumably there's more here
}
You might want to write some helper methods though:
if (IsAnyNonNull(AddressLine1, AddressLine2, Town, Country))
{
if (IsAnyNull(AddressLine1, AddressLine2, Town, Country))
{
return false;
}
}
Where the utility methods would be something like:
public static bool IsAnyNonNull(params object[] values)
{
return values.Any(x => x != null);
}
public static bool IsAnyNull(params object[] values)
{
return values.Any(x => x == null);
}
Of course, you've still got two if statements - but I think that's basically necessary here anyway.
If you make an array of the fields in the group, then you can do:
var fields = new object[] {AddressLine1, AddressLine2, Town, Country};
return fields.All(f => f == null) || fields.All(f => f != null);
Define this:
public static bool SameNullness(params object[] values)
{
int nullCount = 0;
foreach (var value in values)
{
if (value == null) nullCount++;
}
return nullCount == values.Length;
}
Then use it like:
SameNullness(AddressLine1, AddressLine2, Town, Country);

Resources