Sort Java Strings in a Collection using Collator

           Collections.sort(parentList, new Comparator<ListParentAdapter.Parent>() {
                @Override
                public int compare(ListParentAdapter.Parent o1, ListParentAdapter.Parent o2) {

                    //return o1.getName().compareToIgnoreCase(o2.getName());

                    Locale locale=new Locale("fa","IR");
                    Collator collator= Collator.getInstance(locale);
                    return collator.compare(o1.getName(),o2.getName());
                }
            });

References
http://tutorials.jenkov.com/java-internationalization/collator.html
https://stackoverflow.com/questions/16949074/sorting-arabic-words-in-java

Run SoftEther VPN Client on Linux

sudo vpnclient start

Run SoftEther VPN Client Manager and configure it, then connect

sudo dhclient vpn_vpn
sudo ip route add 160.235.81.120/32 via 192.168.1.1 dev wlp3s0
sudo ip route del default via 192.168.1.1 dev wlp3s0

Then change the dns in resolv.conf

Detect when the last item is shown on RecyclerView

public abstract class OnVerticalScrollListener
        extends RecyclerView.OnScrollListener {

    @Override
    public final void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        if (!recyclerView.canScrollVertically(-1)) {
            onScrolledToTop();
        } else if (!recyclerView.canScrollVertically(1)) {
            onScrolledToBottom();
        } else if (dy < 0) {
            onScrolledUp();
        } else if (dy > 0) {
            onScrolledDown();
        }
    }

    public void onScrolledUp() {}

    public void onScrolledDown() {}

    public void onScrolledToTop() {}

    public void onScrolledToBottom() {}
}

Useful info

visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();

References
https://stackoverflow.com/questions/26543131/how-to-implement-endless-list-with-recyclerview

Spring CORS No ‘Access-Control-Allow-Origin’ header is present

Enabling CORS for the whole application is as simple as:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

To enable CORS for the whole controller:

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

To enable CORS for the method:

@RestController
@RequestMapping("/account")
public class AccountController {
  @CrossOrigin
  @RequestMapping("/{id}")
  public Account retrieve(@PathVariable Long id) {
    // ...
  }
}

References
https://stackoverflow.com/questions/35091524/spring-cors-no-access-control-allow-origin-header-is-present

Java BACnet

Build.gradle

repositories {
    maven {
        url "https://maven.mangoautomation.net/repository/ias-release/"
    }
}
compile group: 'com.serotonin', name: 'bacnet4j', version: '4.0.1'

Read and Write Values

public class Main {

    private static LocalDevice localDevice;
    private static RemoteDevice remoteDevice;

    public static void main(String[] args) {
        try {

            IpNetwork network = new IpNetworkBuilder().
                    withBroadcast("192.168.1.255", 24).
                    build();

            Transport transport = new DefaultTransport(network);
            localDevice = new LocalDevice(6, transport);


            localDevice.initialize();

            remoteDevice = localDevice.getRemoteDeviceBlocking(6);

            DiscoveryUtils.getExtendedDeviceInformation(localDevice, remoteDevice);

            /*List oids = ((SequenceOf) RequestUtils.sendReadPropertyAllowNull(localDevice, remoteDevice,
                    remoteDevice.getObjectIdentifier(), PropertyIdentifier.objectList)).getValues();*/

            List<ObjectIdentifier> objectIdentifierList = new ArrayList<ObjectIdentifier>();

            /*for (Object obj : oids) {
                if (obj.getClass().equals(ObjectIdentifier.class)) {
                    ObjectIdentifier oid = (ObjectIdentifier) obj;

                    if (oid.getInstanceNumber() == 85) {
                        if (oid.getObjectType() == ObjectType.binaryOutput) {
                            objectIdentifierList.add(oid);
                        }
                    }
                }
            }*/

            ObjectIdentifier objectIdentifier = new ObjectIdentifier(ObjectType.binaryOutput, 85);
            objectIdentifierList.add(objectIdentifier);
            readPresentValues(objectIdentifierList);
            //readPresentValue(objectIdentifier);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private static void readPresentValues(List<ObjectIdentifier> oids) throws BACnetException {
        PropertyReferences references = new PropertyReferences();

        for (ObjectIdentifier oid : oids) {
            references.add(oid, PropertyIdentifier.presentValue);
        }

        PropertyValues values = RequestUtils.readProperties(localDevice, remoteDevice, references, null);

        for (ObjectIdentifier oid : oids) {
            System.out.println(values.getString(oid, PropertyIdentifier.presentValue));
        }
    }

    private static void readPresentValue(ObjectIdentifier oid) throws Exception {
        ReadPropertyRequest rpr = new ReadPropertyRequest(oid,
                PropertyIdentifier.presentValue);
        ReadPropertyAck ack = (ReadPropertyAck) localDevice.send(remoteDevice, rpr);
        System.out.println("Present value: " + ack.getValue());
    }

    private static void setPresentValue(ObjectIdentifier oid, Encodable value, int priority) throws Exception {
        WritePropertyRequest wpr = new WritePropertyRequest(oid,
                PropertyIdentifier.presentValue, null, value, new UnsignedInteger(priority));
        localDevice.send(remoteDevice, wpr);
    }

    private static void getPriorityArray(ObjectIdentifier oid) throws Exception {
        ReadPropertyRequest rpr = new ReadPropertyRequest(oid,
                PropertyIdentifier.priorityArray);
        ReadPropertyAck ack = (ReadPropertyAck) localDevice.send(remoteDevice, rpr);
        System.out.println("Priority array: " + ack.getValue());
    }
}

References
https://github.com/infiniteautomation/BACnet4J
https://www.csimn.com/CSI_pages/BACnet101.html
https://github.com/openmucextensions/bacnet/wiki