I want to create a subclass of BasicPermission to add actions, which according to the the java docs should be possible:
Subclasses may implement actions on top of BasicPermission, if desired.
Here is my initial attempt:
public class BasicPermissionWithActions extends BasicPermission {
String actions;
String[] actionList;
String name;
public BasicPermissionWithActions(String name, String actions) {
super(name, actions);
this.actions = actions;
this.actionList = actions.split("\\,");
this.name = name;
}
private static final long serialVersionUID = 7608854273379948062L;
#Override
public boolean implies(Permission p) {
// name and class check can be done by super
if (!super.implies(p))
return false;
// now check actions
String requestedActions = p.getActions();
String[] requestedActionList = requestedActions.split("\\,");
for (String requestedAction : requestedActionList) {
if (!hasRequestedAction(requestedAction))
return false;
}
return true;
}
private boolean hasRequestedAction(String requestedAction) {
for (String action : actionList) {
if (action.equals(requestedAction))
return true;
}
return false;
}
#Override
public String getActions() {
return actions;
}
#Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((actions == null) ? 0 : actions.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
BasicPermissionWithActions other = (BasicPermissionWithActions) obj;
if (actions == null) {
if (other.actions != null)
return false;
} else if (!actions.equals(other.actions))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
#Override
public String toString() {
return "(\"" + this.getClass().getName() + "\" \"" + name + "\" \"" + actions + "\")";
}
And an entry in the policy file to grant access using this permission (in this case I'm specify a permission which should be insufficient to allow the desired action):
grant principal sample.principal.SampleGroup "TestGroup" {
permission BasicPermissionWithActions "*", "read";
};
And the code to check the permission:
rep.getAccessControlContext().checkPermission(new BasicPermissionWithActions(getName(), "write"));
I expect this check to fail since the policy has only specified a read action. However the check passes quietly.
The problem is that whenever the permission in the policy file has name "*", the actions are never checked. Running in debug mode shows that the method BasicPermissionWithActions.implies method is never called.
If I omit the permission from the policy file I get a security exception as expected but I cannot make actions work.
The problem is related to PermissionCollection. BasicPermission implements its own PermissionCollection for better performance. Unfortunately, this implementation makes some simplifying assumptions which break the semantics for subclasses. Specifically it implements a shortcut for "*" which bypasses the Permission.implies method and always returns true.
The solution is to implement a custom PermissionCollection which simply calls the Permission.implies methods of its members:
private class CustomPermissionCollection extends PermissionCollection {
private static final long serialVersionUID = 5654758059940546018L;
Collection<Permission> perms = new ArrayList<Permission>();
#Override
public void add(Permission permission) {
perms.add(permission);
}
#Override
public boolean implies(Permission permission) {
for (Permission p : perms) {
if (p.implies(permission))
return true;
}
return false;
}
#Override
public Enumeration<Permission> elements() {
return Collections.enumeration(perms);
}
}
and return this in the newPermissionCollection method of BasicPermissionWithActions
#Override
public PermissionCollection newPermissionCollection() {
return new CustomPermissionCollection();
}
Related
I want to send MeasurementValues to Cumulocity and visualize the data with the given tools. Which values are sent by my software is specified in a JSON and has to be changeable after compilation.
My issue:
The Java Cumulocity Framework doesn't allow me to specify the Name of the measurement fragment that will be displayed on their Website. The name is always the class name of the POJO I used to create the measurement. Since I want to send many different variables (which ones will also change over time), it isn't viable to just create many POJO classes beforehand.
My question:
How can I - sending measurements from one class - display different values in Cumulocity with different names using the Java Cumulocity Framework?
What I tried so far:
There is no measurement property that allows me to change the displayname
There is no way to change a class name at runtime (it's compiled ^^)
The Cumulocity Java Framework doesn't give me direct access to the property
I don't know if I fully understand which name of a measurement you want to change, but I'm assuming you mean the name of the measurement fragment.
When you have created a custom measurement in your Java project you have the possibility to annotate it with #Alias to provide your custom name
package c8y.tinkerforge.measurements;
import java.math.BigDecimal;
import org.svenson.AbstractDynamicProperties;
import org.svenson.JSONProperty;
import com.cumulocity.model.measurement.MeasurementValue;
import com.cumulocity.model.util.Alias;
#Alias("c8y_Acceleration")
public class AccelerationCombinedMeasurement extends AbstractDynamicProperties {
private static final long serialVersionUID = -2491579656609755745L;
public static final String DEFAULT_UNIT = "g";
private final String unit;
private MeasurementValue accelerationX;
private MeasurementValue accelerationY;
private MeasurementValue accelerationZ;
public AccelerationCombinedMeasurement(double accelerationX, double accelerationY, double accelerationZ,
final String unit) {
this.unit = unit;
this.accelerationX = new MeasurementValue(new BigDecimal(accelerationX), unit);
this.accelerationY = new MeasurementValue(new BigDecimal(accelerationY), unit);
this.accelerationZ = new MeasurementValue(new BigDecimal(accelerationZ), unit);
}
#JSONProperty("accelerationX")
public MeasurementValue getAccelerationX() {
return accelerationX;
}
public void setAccelerationX(double accelerationX) {
this.accelerationX = new MeasurementValue(new BigDecimal(accelerationX), unit);
}
#JSONProperty("accelerationY")
public MeasurementValue getAccelerationY() {
return accelerationY;
}
public void setAccelerationY(double accelerationY) {
this.accelerationY = new MeasurementValue(new BigDecimal(accelerationY), unit);
}
#JSONProperty("accelerationZ")
public MeasurementValue getAccelerationZ() {
return accelerationZ;
}
public void setAccelerationZ(double accelerationZ) {
this.accelerationZ = new MeasurementValue(new BigDecimal(accelerationZ), unit);
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((accelerationX == null) ? 0 : accelerationX.hashCode());
result = prime * result + ((accelerationY == null) ? 0 : accelerationY.hashCode());
result = prime * result + ((accelerationZ == null) ? 0 : accelerationZ.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AccelerationCombinedMeasurement other = (AccelerationCombinedMeasurement) obj;
if (accelerationX == null) {
if (other.accelerationX != null)
return false;
} else if (!accelerationX.equals(other.accelerationX))
return false;
if (accelerationY == null) {
if (other.accelerationY != null)
return false;
} else if (!accelerationY.equals(other.accelerationY))
return false;
if (accelerationZ == null) {
if (other.accelerationZ != null)
return false;
} else if (!accelerationZ.equals(other.accelerationZ))
return false;
return true;
}
#Override
public String toString() {
return "AccelerationCombinedMeasurement [accelerationX=" + accelerationX + ", accelerationY=" + accelerationY
+ ", accelerationZ=" + accelerationZ + "]";
}
}
In this case it should use the name c8y_Acceleration. When I create a datapoint graph for a sensor which uses this measurment class you get this:
You can see the name in the red outline.
I am trying to retrieve some values from a Hash Map, before returning the value I am checking if the key is present in the map or not, and this check always fails which results in null value. I have overridden hash Code and equals method as well. Could someone tell me what I am doing wrong here?
class fields:
private static final List<String> DZ=new ArrayList<String>();
private static final Map<Participant,List<String>> subDz=new HashMap<Participant,List<String>>();
Method where I am putting into the map:
public static synchronized void handleSubs(String[] subData,String dz){
int[] lowdims=new int[subData.length];
int[] highdims=new int[subData.length];
try {
for (int i=1;i<subData.length;i++){
if (!subData[i].equals("") && !subData[i].equals("\n")){
if (i%2==0){
highdims[i]=Integer.parseInt(subData[i].trim());
}
else {
lowdims[i]=Integer.parseInt(subData[i].trim());
}
}
}
if (!DZ.isEmpty()){
DZ.clear();
}
DZ.add(dz);
allSubDZs.add(dz);
int[] newlow=removeZeroes(lowdims);
int[] newhigh=removeZeroes(highdims);
allSubs.add(new Participant(newlow,newhigh));
subDz.put(new Participant(newlow,newhigh),DZ );
}
Method where I am retrieving the values:
public static List<String> getSubDz(Participant sub){
if (subDz.containsKey(sub)){
return subDz.get(sub);
}
else{
logger.info("Subscription DZ not available");
return null;
}
}
The if check in the getSubDz always fails, even though I put the key in it.
hashCode and equals methods:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((DZ == null) ? 0 : DZ.hashCode());
return result;
}
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
final SubscriptionHandler other=(SubscriptionHandler)obj;
if (DZ == null) {
if (other.DZ != null) {
return false;
}
} else if (!DZ.equals(other.DZ)) {
return false;
}
return true;
You need equals and hashcode on the key class. This would be the class Participant in your case.
I have the problem, that my equals method doesnt work as i want it to. I want to implement a deterministic turing machine, so I want to add the method findCommand(), which searchs through a arraylist of commands. So I decided to create a searchDummy to find all Transitions that are available for the Configuration I have.
Class States:
public class States {
private int stateId;
private boolean rejState;
private boolean accState;
private boolean stopState;
private List<Commands> commands = new ArrayList<Commands>();
equals in class States:
#Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (other instanceof States) {
States otherState = (States) other;
return (stateId == otherState.stateId);
} else {
return false;
}
}
hashCode:
#Override public int hashCode() {
StringBuilder b = new StringBuilder(stateId);
return b.toString().hashCode();
}
this is the findCommand method in States:
public Commands findCommand(States state, char inputTapeChar,
char[] tapeChars) {
Commands searchDummy = new Commands(state, inputTapeChar, tapeChars,
null, null, null, null);
int pos = commands.indexOf(searchDummy);
return pos >= 0 ? commands.get(pos) : null;
}
commands is my arraylist, so I want to find the searchDummy with indexOf().
I have the class Commands, which holds the attribute Configuration configuration, the class Configuration, which holds the attributes of a Configuration and the attribute Transition transition and the class transition that holds the attributes for itself.
Class Commands:
public class Commands implements Comparable<Commands> {
private Configuration configuration;
Class Configuration:
public class Configuration {
private Transition transition;
private States state;
private char inputTapeChar;
private char[] tapeChars;
Class Transition:
public class Transition {
private States targetState;
private Direction inputTapeHeadMove;
private char[] newTapeChars;
private Direction[] tapeHeadMoves;
i have this equals method in Commands:
#Override public boolean equals(Object other) {
if (this == other) {
return true;
} else if (other instanceof Commands) {
Commands otherCmd = (Commands) other;
return (configuration.equals(otherCmd.configuration));
} else {
return false;
}
}
and this hashcode
#Override
public int hashCode() {
StringBuilder b = new StringBuilder(configuration.getState() + ","
+ configuration.getInputTapeChar());
for (char c : configuration.getTapeChars()) {
b.append("," + c);
}
return b.toString().hashCode();
}
then almost the same in Configuration:
#Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (other instanceof Configuration) {
Configuration otherConfi = (Configuration) other;
return (state.equals(otherConfi.state))
&& (inputTapeChar == otherConfi.inputTapeChar)
&& (Arrays.equals(tapeChars, otherConfi.tapeChars));
} else {
return false;
}
}
hashcode:
#Override
public int hashCode() {
StringBuilder b = new StringBuilder(state + "," + inputTapeChar);
for (char c : tapeChars) {
b.append("," + c);
}
return b.toString().hashCode();
}
equales in class State:
#Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (other instanceof States) {
States otherState = (States) other;
return (stateId == otherState.stateId);
} else {
return false;
}
}
so my question:
when I debug this it goes through until it's finished with the checks but when it should return the value it stucks at Configuration.equals(...) and shows the error no source found!
what is the problem? Are the hashcodes wrong? Or are the equals wrong?
I never used equals before so I dont know when i need to use it or how i need to fix this. thanks for your help.
Your hashCode implementation looks suspect - all that String stuff is not standard.
For example for your Transition class should be something like this:
#Override
public int hashCode() {
int result = 17;
result = 31 * result + targetState.hashCode();
result = 31 * result + inputTapeHeadMove.hashCode();
result = 31 * result + newTapeChars.hashCode();
result = 31 * tapeHeadMoves.hashCode();
return result;
}
Most IDEs will offer autogen of hashCode and equals methods.
I want specific object with all it's values by using it's unique id of object from object list.
I have tried but i am getting index -1 while running below code.
List<JobDataDetail> jobList = getJobList();
JobDataDetail object = jobList.get(jobList.indexOf(new JobDataDetail(jobReferenceId)));
from the class
public class JobDataDetail implements Serializable,Comparable<JobDataDetail> {
public int jobSequence;
public String jobReferenceId;
public String jobAddress;
public String jobScheduledDate;
public JobDataDetail() {
super();
// TODO Auto-generated constructor stub
}
public JobDataDetail(int jobSequence){
super();
this.jobSequence = jobSequence ;
}
public JobDataDetail(String jobReferenceId){
super();
this.jobReferenceId = jobReferenceId;
}
public int getJobSequence() {
return jobSequence;
}
public void setJobSequence(int jobSequence) {
this.jobSequence = jobSequence;
}
public String getJobReferenceId() {
return jobReferenceId;
}
public void setJobReferenceId(String jobReferenceId) {
this.jobReferenceId = jobReferenceId;
}
public String getJobAddress() {
return jobAddress;
}
public void setJobAddress(String jobAddress) {
this.jobAddress = jobAddress;
}
public String getJobScheduledDate() {
return jobScheduledDate;
}
public void setJobScheduledDate(String jobScheduledDate) {
this.jobScheduledDate = jobScheduledDate;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((jobReferenceId == null) ? 0 : jobReferenceId.hashCode());
result = prime * result + jobSequence;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
JobDataDetail other = (JobDataDetail) obj;
if (jobReferenceId == null) {
if (other.jobReferenceId != null)
return false;
} else if (!jobReferenceId.equals(other.jobReferenceId))
return false;
if (jobSequence != other.jobSequence)
return false;
return true;
}
#Override
public int compareTo(JobDataDetail another) {
return this.getJobReferenceId().compareTo(another.getJobReferenceId());
}
}
List.indexOf() uses equals() method to compare objects.
In your case, you are assuming that two objects with same jobReferenceId are equals but your equals() method doesn't say so (because of the jobSequence test at the end of your method).
If you want to get an item from your list by one of its attribute, the easiest way would be using filter expression in Java 8:
JobDataDetail job = jobList.stream()
.filter(j -> j.getAttribute().equals(someValue))
.findFirst();
If Java 8 is not an option, I would go for a classic for loop iterating over the list.
I have removed jobSequence condition check from equals method and it's working.
I am developing an Android application which makes use of the ScanResult object. This object is in the form of:
[SSID: __mynetwork__, BSSID: 00:0e:2e:ae:4e:85, capabilities: [WPA-PSK-TKIP][ESS], level: -69, frequency: 2457, timestamp: 117455824743]
How would I override only the equals() method without creating a customer class which extends it in order to compare only the SSID, BSSID, capabilties, level and frequency attributes only? In other words, in the equals method I want to eliminate the timestamp attribute, so that when I compare these two objects, the equals() method would return a true value:
[SSID: __mynetwork__, BSSID: 00:0e:2e:ae:4e:85, capabilities: [WPA-PSK-TKIP][ESS], level: -69, frequency: 2457, timestamp: 117455824743]
[SSID: __mynetwork__, BSSID: 00:0e:2e:ae:4e:85, capabilities: [WPA-PSK-TKIP][ESS], level: -69, frequency: 2457, timestamp: 117460312231]
Note: When I derive a customer class which extends ScanResult I get the following error when I try to implement a constructor: The constructor ScanResult() is not visible
You just have to implement it without checking the fields you want to ignore. Don't forget to override the hashode() too.
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((field1 == null) ? 0 : field1.hashCode());
result = prime * result + ((field2 == null) ? 0 : field2.hashCode());
...etc
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ScanResult other = (ScanResult ) obj;
if (field1 == null) {
if (other.field1 != null)
return false;
} else if (!field1.equals(other.field1))
return false;
if (field2 == null) {
if (other.field2 != null)
return false;
} else if (!field2 .equals(other.field2 ))
return false;
}
... etc
}
This is your Overriden equals() Method....
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ScanResult)) return false;
if(!BSSID.equals(o.BSSID)) return false;
if(!SSID.equals(o.SSID)) return false;
if(!capabilities.equals(o.capabilities)) return false;
if(frequency != o.frequency) return false;
if(level != o.level) return false;
return true;
}
EDIT
Now that the above solution not working, may I suggest:
class ScanResultComparator {
public static boolean equals(ScanResult a, ScanResult b){
if(!a.BSSID.equals(b.BSSID)) return false;
if(!a.SSID.equals(b.SSID)) return false;
if(!a.capabilities.equals(b.capabilities)) return false;
if(a.frequency != b.frequency) return false;
if(a.level != b.level) return false;
return true;
}
}
Extend the ScanResult class and only override the equals() method
class CustomScanResult extends ScanResult {
#Override
public boolean equals(Object o) {
// ... custom logic ...
}
}
simple way use check all variables for true.
example:
public class FtpFile {
public String host;
public String port;
public String fileName;
public String path;
public String username;
public String password;
/**
* Override Equals()
*/
#Override
public boolean equals(Object o) {
try {
if (o == null || getClass() != o.getClass())
return false;
FtpFile p = (FtpFile) o;
return ((host.equals(p.host))
&& (port.equals(p.port))
&& (path.equals(p.path))
&& (username.equals(p.username))
&& (password.equals(p.password)));
} catch (Exception ex) {
return false;
}
}
}