I only want to check for:
if (lore.contains("§eSigned of ")) {
but it doesn't get that it does contain "§eSigned of "
I wrote a Minecraft Command /sign you can add a lore to an item ("Signed of playerrank | playername").
Then i wanted to add an /unsign command to remove this lore.
ItemStack is = p.getItemInHand();
ItemMeta im = is.getItemMeta();
List<String> lore = im.hasLore() ? im.getLore() : new ArrayList<String>();
if (lore.contains("§eSigned of " + getChatName(p))) { // this line is important!
for (int i = 0; i < 3; i++) {
int size = lore.size();
lore.remove(size - 1);
}
im.setLore(lore);
is.setItemMeta(im);
p.setItemInHand(is);
sendMessage(p, "§aThis item is no longer signed");
} else {
sendMessage(p, "§aThis item is not signed!");
}
return CommandResult.None;
Everything works fine until you e.g. change your name. than you can't remove the sign because getChatName(p) has changed.
To fix this i only want to check
if (lore.contains("§eSigned of ")) {
but than it doesn't get it and returns false. (it says lore does not contain "§eSigned of ")
I tried a lot but it only works with the string "§eSigned of " and getChatName(p).
As the documentation "contains" searches for the specific string so it should work as I thought right?
Add:
getChatName(p) returns the rank of the player and the playername like: "Member | domi"
sendMessage(p, "") sends a simple message in the Minecraft chat
The problem you run into is that contains(String) looks for a matching string. What you search for is a check if any string in the list starts with "§eSigned of ".
I would suggest adding a function isSignedItem like this:
private boolean isSignedItem(List<String> lore) {
for (String st : lore)
if (st.startsWith("§eSigned of "))
return true;
return false;
}
and then to use this function to check if the item is signed or not:
[...]
List<String> lore = im.hasLore() ? im.getLore() : new ArrayList<String>();
if (isSignedItem(lore)) { // this line is important!
for (int i = 0; i < 3; i++) {
int size = lore.size();
lore.remove(size - 1);
}
[...]
I am new to Java and practicing parsing csv file into the object. I've tried but cannot figure it out.
The file looks like this:
[0], [1], [2], [3] , [4] , [5] , [6] , [7] , [8] , [9]
class, gender, age, bodyType, profession, pregnant, isYou ,species, isPet, role
scenario:green, , , , , , , ,
person, female, 24, average , , FALSE , , , , passenger
animal, male , 4, , , FALSE , , dog , TRUE , pedestrian
scenario:red
person, male , 16, athletic, boxer , FALSE , TRUE , , , passenger
person, female, 25, athletic, doctor , TRUE , FALSE , , , pedestrian
I need to parse it by any number of passengers and pedestrians with any scenarios. Finally, add these scenarios into an ArrayList for analyzing.
What I think is to:
loop through each line, stops when reaches to the next scenario:red, adds the passengers and the pedestrians to the Character ArrayList. (I've done adding, but don't how to stop).
Create a scenario using constructor scenario(ArrayList<Character> passenger, ArrayList<Character> pedestrians, boolean redOrGreen);
The ArrayList scenarios add the created scenarios.
What I've done is put everything together instead of separate them. Any help or hint is highly appreciated.
Thanks for this community who helped me, here is what I've got so far.
public void loadCsv() throws IOException {
String csvFile = "config.csv";
String line = "";
String csvSplit = "\\s*,\\s*";
Scenario scenario = new Scenario();
Person person = new Person();
Animal animal = new Animal();
ArrayList<Scenario> scenaios = new ArrayList<Scenario>();
ArrayList<String> csvContents = new ArrayList<String>();
ArrayList<Character> passengers = new ArrayList<Character>();
ArrayList<Character> pedestrians = new ArrayList<Character>();
try (BufferedReader csvReader = new BufferedReader(new FileReader(csvFile));) {
String headerLine = csvReader.readLine(); //get rid of the header
//add each line to the arrayList
while ((line = csvReader.readLine()) != null) {
csvContents.add(line);
}
for(String csvLine : csvContents) {
String[] data = csvLine.split(csvSplit); // split by comma and remove redundant spaces
if (data.length == NO_OF_FIELD) { //check and avoid indexOutOfBoundException
String clazz = data[0].toLowerCase();// cannot use word "class" as a variable
if (clazz.startsWith("scenario") && data.length == 1) {
scenario = new Scenario();
scenario.setLegalCrossing(clazz.endsWith("green"));
continue;
}
else if ("person".equals(clazz) && data.length ==10) {
person = loadCsvPerson(data);
addCharacter(person, data);
}
else if ("animal".equals(clazz) && data.length ==10) {
animal = loadCsvAnimal(data);
addCharacter(animal, data);
}
}
}
}
//passenger and pedestrians are in position
System.out.println("passengers: " + passengers);
System.out.println("pedestrians: " + pedestrians);
if (null != scenario) {
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
If it is possible to change the csv file format, I would add scenario type column (and scenario id or name if required), so you can work with csv file as a result set from database when you join tables (scenario + passenger + pedestrian) and return plain rows.
With this approach you will be able to delegate parsing to any csv library and do your logic (group by scenario id/name/type) separately. With surrogate rows you have (scenario:green...) you have to write your custom parser.
For example, you can use univocity to simply parse file into your model (even using annotations) and iteratively group it and handle.
Or if you need to work with existing file format do something like that:
if (clazz.startsWith("scenario") && data.length == 1) {
// collect existing scenario before starting processing new one
if (scenario != null) {
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
passengers = new ArrayList();
pedestrians = new ArrayList();
scenarios.add(scenario);
}
// now start new group (scenario)
scenario = new Scenario();
scenario.setLegalCrossing(clazz.endsWith("green"));
continue;
}
Following things need to be addressed in your code:
Strive to avoid using the name of a class which is already used by the standard library (and especially when it is in the default package, java.lang) e.g. there is already a class Character in Java library and therefore you should use a different name for your custom class.
Use continue to skip the line, scenario:red
for(String csvLine : csvContents) {
if(csvLine.equals("scenario:red")){
continue;
}
String[] data = csvLine.split(csvSplit); // split by comma and remove redundant spaces
if (data.length == NO_OF_FIELD) {
//..
}
//..
}
If you have already defined final int NO_OF_FIELD = 10, you can use the same instead of using the value 10 directly i.e. you should use NO_OF_FIELD instead of 10 in the following code:
if (data.length == NO_OF_FIELD) { //check and avoid indexOutOfBoundException
String clazz = data[0].toLowerCase();// cannot use word "class" as a variable
//...
else if ("person".equals(clazz) && data.length ==10) {
However, you also need to understand that && data.length ==10 is unnecessary here as you have already checked data.length == NO_OF_FIELD in the enclosing if condition.
I couldn't understand the rest of your points. If you clarify them, I'll be able to help you further.
I need to add the previous scenario in the second round.
Since the last set of data won't be captured, I need to set another new scenario to add it in. Thanks for the art sir.
Character character = null;
try (BufferedReader csvReader = new BufferedReader(new FileReader(csvFile));) {
String headerLine = csvReader.readLine(); //get rid of the header
//add each line to the arrayList
while ((line = csvReader.readLine()) != null) {
csvContents.add(line);
}
final int NO_OF_FIELDS = 10;
for(String csvLine : csvContents) {
String[] data = csvLine.split(csvSplit); // split by comma and remove redundant spaces
String clazz = data[0].toLowerCase();// cannot use word "class" as a variable
if (clazz.startsWith("scenario") && data.length == 1) {
// adding scenario after one set of data
// i.e second round adding the first round data
if (passengers.size() != 0 && pedestrians.size() != 0) {
Scenario scenario = new Scenario();
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
scenarios.add(scenario);
}
passengers = new ArrayList<Character>();
pedestrians = new ArrayList<Character>();
if (clazz.endsWith("green")) {
scenario.setLegalCrossing(true);
System.out.println("green light");
}
else if (clazz.endsWith("red")){
scenario.setLegalCrossing(false);
System.out.println("red light");
}
continue;
}
//...
Scenario scenario = new Scenario();
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
scenarios.add(scenario);
scenario.setPassengers(passengers);
scenario.setPedestrians(pedestrians);
Audit audit = new Audit();
audit.setScenario(scenarios);
I have this code. Whis is searching excel csv and creating .txt file with missing subtitles for movies. One movie can have one or two or three or four subtitles. In excel it is written as Y or N for every language. It is working for one language (INDO). I added other languages (GBR,SIM,MYS) into excel and here.
int INDOSUB = 4;
int GBRSUB = 5;
int SIMSUB = 6;
int MYSSUB = 7;
int KPPNAME = 1;
...
//NEW REQUIREMENT, CHECK PLAYLIST FOR MISSING SUBTITLES
for(int i=0; i < assets.size(); i++)
{
try
{
file = new File(assets.get(i));
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null)
{
tmp = line.split(",");
if(tmp.length > 4)
{
String indosubStatus = tmp[INDOSUB];
String gbrsubStatus = tmp[GBRSUB];
String simsubStatus = tmp[SIMSUB];
String myssubStatus = tmp[MYSSUB];
String kppKey = tmp[KPPNAME];
if(indosubStatus.equals("N"))
{
kppSubitleMap.put(kppKey,"NO INDO SUBTITLES");
kppWithMissingSub.put(tmp[KPPNAME],"");
}
if(gbrsubStatus.equals("N"))
{
kppSubitleMap.put(kppKey,"NO GBR SUBTITLES");
kppWithMissingSub.put(tmp[KPPNAME],"");
}
if(simsubStatus.equals("N"))
{
kppSubitleMap.put(kppKey,"NO SIM SUBTITLES");
kppWithMissingSub.put(tmp[KPPNAME],"");
}
if(myssubStatus.equals("N"))
{
kppSubitleMap.put(kppKey,"NO MYS SUBTITLES");
kppWithMissingSub.put(tmp[KPPNAME],"");
}
}
}
}
catch(IOException ex)
{
System.out.println(ex.toString());
}
}
When it runs it shows only this. And I am sure KPP_Heartless is not having GBR and SIM subtitles either. But it only shows the last one. So it seems its overriding previous record.
KPP_HEARTLESS_19 - NO MYS SUBTITLES
DATE/TIME: 1/11/2017 - 23:45:09:20
DATE/TIME: 1/12/2017 - 04:45:07:21
DATE/TIME: 1/12/2017 - 12:30:08:20
DATE/TIME: 1/12/2017 - 17:30:04:19
KPP_LISTEN_07 - NO INDO SUBTITLES
DATE/TIME: 1/12/2017 - 03:30:11:24
DATE/TIME: 1/12/2017 - 07:30:13:13
DATE/TIME: 1/12/2017 - 15:00:10:10
KPP_LISTEN_08 - NO INDO SUBTITLES
DATE/TIME: 1/12/2017 - 20:00:10:05
KPP_HEARTLESS_20 - NO MYS SUBTITLES
DATE/TIME: 1/12/2017 - 23:45:09:19
Does anybody know how to prevent it from overriding? Thank you very much.
It has no relation with overriding method.
The problems comes that when you write :
kppSubitleMap.put(kppKey,"NO SIM SUBTITLES");
kppWithMissingSub.put(tmp[KPPNAME],"");
you overwrite the value associated to the key.
1) If you want to have multiple values in the map, you could use a List or a Set as values. For example : Map<String, List<String>>.
Here is an example what you should do with the kppSubitleMap map but the problem is the same with kppWithMissingSub.
if(gbrsubStatus.equals("N")){
List<String> values = kppSubitleMap.get(kppKey);
if (values = null){
values = new ArrayList<String>();
}
values.add("NO GBR SUBTITLES");
kppSubitleMap.put(kppKey, values);
...
}
The boiler plate code should be performed in a utility method to avoid repeat yourself in each if block:
public List<String> getOrCreateList(Map<String,List<String>> map, String key){
List<String> values = map.get(kppKey);
if (values = null){
values = new ArrayList<String>();
}
return values;
}
2) If you want to simply concatenate the information you could do it :
String value = kppSubitleMap.get(kppKey);
if (value==null){
value = "";
}
value += "NO GBR SUBTITLES");
kppSubitleMap.put(kppKey, value );
When you invoke Map.put() several times Map contains just last value for the same key. You can use Map<String, Set<String>>
Example:
Set<String> values = kppSubitleMap.get(kppKey);
if (values == null) {
values = new HashSet<>();
kppSubitleMap.put(kppKey, values);
}
values.add("NO GBR SUBTITLES")
or use Guava.Multimaps
I'd like to retrieve data from string based on params from template.
For example:
given string -> "some text, var=20 another part param=45"
template -> "some text, var=${var1} another part param=${var2}"
result -> var1 = 20; var2 = 45
How could I achive that result in Java. Are there some libs or I need to use regex?
I tried different template processors, but they don't have needed functionality, I need something like inverse to them.
I hope below sample will serve your purpose -
String strValue = "some text, var=20 another part param=45";
String strTemplate = "some text, var=${var1} another part param=${var2}";
ArrayList<String> wildcards = new ArrayList<String>();
StringBuffer outputBuffer = new StringBuffer();
Pattern pat1 = Pattern.compile("(\\$\\{\\w*\\})");
Matcher mat1 = pat1.matcher(strTemplate);
while (mat1.find())
{
wildcards.add(mat1.group(1).replaceAll("\\$", "").replaceAll("\\{", "").replaceAll("\\}", ""));
strTemplate = strTemplate.replace(mat1.group(1), "(\\w*)");
}
if(wildcards!= null && wildcards.size() > 0)
{
Pattern pat2 = Pattern.compile(strTemplate);
Matcher mat2 = pat2.matcher(strValue);
if (mat2.find())
{
for(int i=0;i<wildcards.size();i++)
{
outputBuffer.append(wildcards.get(i)).append(" = ");
outputBuffer.append(mat2.group(i+1));
if(i != wildcards.size()-1)
{
outputBuffer.append("; ");
}
}
}
}
System.out.println(outputBuffer.toString());
i'm trying to get folder structure of a rule using java TEAMSERVER API .
IlrSessionFactory factory = new IlrRemoteSessionFactory();
try {
factory.connect(login, password, serverUrl, datasource);
IlrSession session = factory.getSession();
IlrRuleProject ruleProject = (IlrRuleProject) IlrSessionHelper.getProjectNamed(session, project);
IlrBaseline currentBaseline = IlrSessionHelper.getCurrentBaseline(session, ruleProject);
session.setWorkingBaseline(currentBaseline);
String query = new String("Find all business rules such that the name of each business rule is \"R105_1_krl\"");
IlrDefaultSearchCriteria criteria = new IlrDefaultSearchCriteria( query.toString());
List summaries = session.findElements(criteria, IlrModelConstants.ELEMENT_SUMMARY);
for (int i = 0; i < summaries.size(); i++) {
IlrElementSummary ruleSummary = (IlrElementSummary) summaries.get(i);
String ruleName = ruleSummary.getName();
System.out.println("\t" + ruleName);
}
If there is as named R105_1_krl rule , I can reach using java and DECİSİON CENTER API. But i need location of this rule. Such as XYZ package / abc folder / def folder
In addition , when i wrote the following two line in loop , i can reach these properties ;
Expiration Date, Effective Date, Created By, Last Changed On ... But, i can not reach folder information of properties of a rule.
IlrActionRule rule = (IlrActionRule) elementDetails;
String lastChangedBy = String.valueOf(rule.getPropertyValue("lastChangedBy"));
Here is the solution.
public static String getHierarchyPath (IlrElementDetails element) {
try {
if (!(element instanceof IlrRule)) return element.getName();
IlrRule rule = (IlrRule)element;
StringBuffer sb = new StringBuffer ();
// Get the rule name
String name = rule.getName();
// Get the rule package
IlrRulePackage current = rule.getRulePackage();
Stack<String> stack = new Stack<String> ();
while (true) {
if (current==null) break;
// Push the package name onto the stack
stack.push("/" + current.getName());
// Next parent ...
current = current.getParent();
}
// Pop the stack and build the path
while (!stack.empty()) {
String folder = (String) stack.pop();
sb.append(folder);
}
// Append the rule name to the path
sb.append("/").append(name);
// Return the built path
return sb.toString();
} catch (Exception e) {
return element.getName();
}
}