Premier commit - Inclusion dans le projet git
This commit is contained in:
commit
f8c170b29a
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
bin/
|
||||
discordout.ods
|
||||
testout.ods
|
||||
testoutout.ods
|
||||
44
src/com/bernard/math/GraphFunctions.java
Normal file
44
src/com/bernard/math/GraphFunctions.java
Normal file
@ -0,0 +1,44 @@
|
||||
package com.bernard.math;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.bernard.math.graph.GraphCycleException;
|
||||
|
||||
public class GraphFunctions {
|
||||
|
||||
public static <S,T> boolean anyCycle(Map<S,List<T>> heritages,Function<T,S> fonction) {
|
||||
Set<S> patouché = new HashSet<S>(heritages.keySet());
|
||||
Set<S> traitage = new HashSet<>();
|
||||
try {
|
||||
while(!patouché.isEmpty()) {
|
||||
S el = patouché.stream().findAny().get();
|
||||
traitation(el,patouché,traitage,heritages,fonction);
|
||||
}
|
||||
}catch (GraphCycleException ex) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static <S,T> void traitation(S s, Set<S> patouché, Set<S> traitage, Map<S,List<T>> heritages,Function<T,S> fonction) throws GraphCycleException{
|
||||
patouché.remove(s);
|
||||
if(!heritages.containsKey(s))
|
||||
return;
|
||||
traitage.add(s);
|
||||
for(T heritation : heritages.get(s)) {
|
||||
S enfant = fonction.apply(heritation);
|
||||
if(patouché.contains(enfant))
|
||||
traitation(enfant,patouché,traitage,heritages,fonction);
|
||||
if(traitage.contains(enfant))
|
||||
throw new GraphCycleException();
|
||||
// Sinon, ça ne peut pas faire de cycle: parfait !
|
||||
}
|
||||
traitage.remove(s);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
59
src/com/bernard/math/SortFunctions.java
Normal file
59
src/com/bernard/math/SortFunctions.java
Normal file
@ -0,0 +1,59 @@
|
||||
package com.bernard.math;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SortFunctions {
|
||||
|
||||
public static <T> int compare(Set<T> s1,Set<T> s2,Comparator<T> cprt){
|
||||
|
||||
// Premier ordre: inclusion
|
||||
if(s1.containsAll(s2))
|
||||
return 1;
|
||||
if(s2.containsAll(s1))
|
||||
return -1;
|
||||
|
||||
//TODO: Refaire cette fonction un peu plus proprement …
|
||||
|
||||
// Second ordre: Majoration de chaque terme
|
||||
List<T> lt1 = s1.stream().sorted(cprt).collect(Collectors.toList());
|
||||
List<T> lt2 = s2.stream().sorted(cprt).collect(Collectors.toList());
|
||||
|
||||
// Si lt1 < lt2 ?
|
||||
int i=0,j=0;
|
||||
while(i<lt1.size() && j<lt2.size()) {
|
||||
int val = cprt.compare(lt1.get(i), lt2.get(j));
|
||||
if(val<0)
|
||||
i++;
|
||||
else if(val>0)
|
||||
break;
|
||||
}
|
||||
if(i<lt1.size() && j<lt2.size())
|
||||
return -1;
|
||||
|
||||
// Si lt1 < lt2 ?
|
||||
i=0;
|
||||
j=0;
|
||||
while(i<lt1.size() && j<lt2.size()) {
|
||||
int val = cprt.compare(lt2.get(i), lt1.get(j));
|
||||
if(val<0)
|
||||
i++;
|
||||
else if(val>0)
|
||||
break;
|
||||
}
|
||||
if(i<lt1.size() && j<lt2.size())
|
||||
return 1;
|
||||
|
||||
//Troisième ordre ……… Du coup … on revient à un tri lexicographique.
|
||||
if(lt1.size()!=lt2.size())
|
||||
return Integer.compare(lt2.size(), lt1.size());
|
||||
for (int k = 0; k < lt1.size(); k++) {
|
||||
if(lt1.get(k)!=lt2.get(k))
|
||||
return cprt.compare(lt1.get(k), lt2.get(k));
|
||||
}
|
||||
return 0; //Là, on a vraiment tous les termes triés égaux, donc. On peut dire qu'il y a égalité ^^
|
||||
}
|
||||
|
||||
}
|
||||
7
src/com/bernard/math/graph/GraphCycleException.java
Normal file
7
src/com/bernard/math/graph/GraphCycleException.java
Normal file
@ -0,0 +1,7 @@
|
||||
package com.bernard.math.graph;
|
||||
|
||||
public class GraphCycleException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = -39387746213824654L;
|
||||
|
||||
}
|
||||
7
src/com/bernard/permissions/PermissionContext.java
Normal file
7
src/com/bernard/permissions/PermissionContext.java
Normal file
@ -0,0 +1,7 @@
|
||||
package com.bernard.permissions;
|
||||
|
||||
public interface PermissionContext<Perm,Permholder> {
|
||||
|
||||
public boolean can(Perm p, Permholder ph);
|
||||
|
||||
}
|
||||
247
src/com/bernard/permissions/StringPermission.java
Normal file
247
src/com/bernard/permissions/StringPermission.java
Normal file
@ -0,0 +1,247 @@
|
||||
package com.bernard.permissions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.bernard.math.SortFunctions;
|
||||
|
||||
public class StringPermission implements Comparable<StringPermission>{
|
||||
|
||||
private Nomme[] nommes;
|
||||
|
||||
public StringPermission(Nomme[] nommes) {
|
||||
this.nommes = nommes;
|
||||
}
|
||||
|
||||
public static boolean implies(StringPermission s1,StringPermission s2) {
|
||||
|
||||
if(s2==null)return true;
|
||||
if(s1==null)return false;
|
||||
if(s2.nommes.length < s1.nommes.length)return false;
|
||||
|
||||
//Bon déjà, ils ont le même nom
|
||||
|
||||
for (int i = 0; i < s1.nommes.length; i++)
|
||||
if(Nomme.implies(s1.nommes[i], s2.nommes[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean implies(StringPermission other) {
|
||||
return implies(this,other);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Définition des regex, avec des variables les unes dans les autres. Sinon c'est pas possible
|
||||
public static final String strR = "(([^\"\\\\]|\\\\\\\\|\\\\\")*)\""; // Without first slash
|
||||
public static final String optionR = "((\""+strR+"|[^=]+)=(\""+strR+"|[^,\\]]+))";
|
||||
public static final String optionsR = "((("+optionR+",)*)"+optionR+")";
|
||||
public static final String nnameR = "([^.\"\\[]+)";
|
||||
public static final String fullNR = "("+nnameR+"(\\["+optionsR+"\\])?)";
|
||||
public static final String spR = "(("+fullNR+"\\.)*)("+fullNR+")";
|
||||
|
||||
public static final Pattern spregex = Pattern.compile(spR);
|
||||
public static final Pattern optsregex = Pattern.compile(optionsR);
|
||||
|
||||
public static StringPermission parse(String str) {
|
||||
|
||||
Nomme[] nommes = recParse(str, 0);
|
||||
|
||||
return new StringPermission(nommes);
|
||||
}
|
||||
|
||||
private static Nomme[] recParse(String str,int index) {
|
||||
|
||||
Matcher mtch = spregex.matcher(str);
|
||||
if(!mtch.matches())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
String optionstr = mtch.group(27);
|
||||
|
||||
String nom = mtch.group(25);
|
||||
|
||||
Map<String,String> options = null;
|
||||
if(optionstr!=null && !optionstr.isEmpty()) {
|
||||
options = new HashMap<>();
|
||||
String roptions = optionstr;
|
||||
Matcher optMtch;
|
||||
do {
|
||||
optMtch = optsregex.matcher(roptions);
|
||||
optMtch.matches();
|
||||
String name = pppstring(optMtch.group(12),optMtch.group(13));
|
||||
String value = pppstring(optMtch.group(15),optMtch.group(16));
|
||||
options.put(name, value);
|
||||
roptions = optMtch.group(2);
|
||||
roptions = roptions.substring(0, Math.max(roptions.length()-1,0));
|
||||
}while(!roptions.isEmpty());
|
||||
}
|
||||
|
||||
Nomme nomme = new Nomme(nom, options);
|
||||
String reste = mtch.group(1);
|
||||
Nomme[] nommes;
|
||||
if(reste.isEmpty()) { //Non null car l'étoile de Kleene match le groupe vide
|
||||
//Dernier parse
|
||||
nommes = new Nomme[index+1];
|
||||
nommes[0] = nomme;
|
||||
}else {
|
||||
nommes = recParse(reste.substring(0, reste.length()-1),index+1); // Pof
|
||||
nommes[nommes.length-1-index] = nomme;
|
||||
}
|
||||
return nommes;
|
||||
}
|
||||
|
||||
public static final String pppstring(String raw,String quoted) {
|
||||
if(quoted!=null) {
|
||||
return quoted.replaceAll("\\\\\\\\", "\\").replaceAll("\\\\\"", "\"");
|
||||
}else {
|
||||
return raw;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String escapeIfNecessary(String raw) {
|
||||
return escapeIfNecessary(raw, true);
|
||||
}
|
||||
public static final String escapeIfNecessary(String raw,boolean canEqualSign) {
|
||||
if(raw.contains("\"") || raw.contains("\\") || (!canEqualSign && raw.contains("=")))
|
||||
return "\"" + raw.replaceAll("\\\\", "\\\\").replaceAll("\"", "\\\"") + "\"";
|
||||
else
|
||||
return raw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(StringPermission sp) {
|
||||
return this.toString().compareTo(sp.toString());
|
||||
}
|
||||
|
||||
@Deprecated //TODO Fix this method with a real order (this one doesn't support nomme's options order)
|
||||
public int compareTo(StringPermission sp,boolean disabled) {
|
||||
int l1=this.nommes.length,l2=sp.nommes.length;
|
||||
for (int k = 0; k < Math.min(l1, l2); k++) {
|
||||
if(this.nommes[k]!=sp.nommes[k])
|
||||
return - this.nommes[k].compareTo(sp.nommes[k]);//TODO: Fix why is this minus sign here
|
||||
}
|
||||
//Ici, tous les points sont égaux. Donc on trie du plus court au plus long.
|
||||
return Integer.compare(l1, l2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(nommes);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
StringPermission other = (StringPermission) obj;
|
||||
if (!Arrays.equals(nommes, other.nommes))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Arrays.stream(nommes).map(Nomme::toString).collect(Collectors.joining("."));
|
||||
}
|
||||
|
||||
|
||||
public static class Nomme implements Comparable<Nomme>{
|
||||
String name;
|
||||
Map<String,String> options;
|
||||
|
||||
public Nomme(String name, Map<String, String> options) {
|
||||
this.name = name;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + ((options!=null)?("[" + options.entrySet().stream()
|
||||
.map(e->escapeIfNecessary(e.getKey(),false)+"="+escapeIfNecessary(e.getKey()))
|
||||
.collect(Collectors.joining(",")) + "]"):"");
|
||||
}
|
||||
|
||||
public static boolean implies(Nomme n1,Nomme n2) {
|
||||
if(n2==null)return true;
|
||||
if(n1==null)return false;
|
||||
if(n2.name.equals(n1.name))return false;
|
||||
|
||||
//Bon déjà, ils ont le même nom
|
||||
if(n1.options == null)return true;
|
||||
if(n2.options == null)return false; //car il ne peut y avoir d'options à n1.
|
||||
if(!n2.options.keySet().containsAll(n1.options.keySet()))return false;
|
||||
|
||||
// Donc Keys(n1) ⊂ Keys(n2)
|
||||
// Il ne reste qu'à tester tous les nommes , si leur valeur est égale (ou absente -> Impossible car inclusion)
|
||||
return n1.options.keySet().stream().allMatch(opt -> n1.options.get(opt).equals(n2.options.get(opt)));
|
||||
}
|
||||
|
||||
public boolean implies(Nomme other) {
|
||||
return implies(this,other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Nomme n) {
|
||||
if(!this.name.equals(n.name))
|
||||
return this.name.compareTo(n.name);
|
||||
if(options==null || n.options==null)
|
||||
return (options==null)?((n.options==null)?0:-1):1;
|
||||
System.out.println("bitenbois");
|
||||
//On ordonne les options
|
||||
return SortFunctions.compare(options.entrySet(),
|
||||
n.options.entrySet(),
|
||||
(e1,e2) -> (e1.getKey()==e2.getKey())
|
||||
?e1.getValue().compareTo(e2.getValue())
|
||||
:e1.getKey().compareTo(e2.getKey()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((options == null) ? 0 : options.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;
|
||||
Nomme other = (Nomme) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (options == null) {
|
||||
if (other.options != null)
|
||||
return false;
|
||||
} else if (!options.equals(other.options))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
126
src/com/bernard/permissions/TestMain.java
Normal file
126
src/com/bernard/permissions/TestMain.java
Normal file
@ -0,0 +1,126 @@
|
||||
package com.bernard.permissions;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import com.bernard.permissions.tableured.FileManager;
|
||||
import com.bernard.permissions.tableured.TPermissionContext;
|
||||
import com.bernard.permissions.tableured.TPermissionContext.Inheritance;
|
||||
import com.bernard.permissions.tableured.TPermissionContext.Val;
|
||||
import com.sun.star.uno.Exception;
|
||||
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.JDABuilder;
|
||||
import net.dv8tion.jda.api.Permission;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.requests.GatewayIntent;
|
||||
|
||||
public class TestMain {
|
||||
|
||||
public static void main(String[] args) throws Exception, LoginException, InterruptedException{
|
||||
|
||||
testDiscordRead();
|
||||
|
||||
System.out.println("OK, i'm done !");
|
||||
System.exit(0);;
|
||||
}
|
||||
|
||||
public static void testReadAndWrite() {
|
||||
try {
|
||||
TPermissionContext tpc = FileManager.readFromFile(new File("test.ods"));
|
||||
String[] perms = {"julia","julia.bdd","julia.bdd.read","julia.bdd.write","julia.messages","julia.coucou"};
|
||||
String[] holders = {"Admin","Developeur","Client","Étranger","Mysaa","Bernard","Zlopeg","Ferbex","Pbalkany"};
|
||||
for (String perm : perms) {
|
||||
for (String holder : holders) {
|
||||
System.out.println(holder+" can "+perm+" : "+tpc.can(StringPermission.parse(perm), holder));
|
||||
}
|
||||
System.out.println("=========================");
|
||||
}
|
||||
System.out.println(tpc);
|
||||
System.out.println("Writing back to file.");
|
||||
|
||||
new File("testout.ods").delete();
|
||||
FileManager.writeToFile(new File("testout.ods"), tpc);
|
||||
System.out.println("Re-reading it");
|
||||
TPermissionContext newTPC = FileManager.readFromFile(new File("testout.ods"));
|
||||
System.out.println(tpc);
|
||||
System.out.println("Equals test: "+tpc.equals(newTPC));
|
||||
System.out.println("Writing to another file");
|
||||
FileManager.writeToFile(new File("testoutout.ods"), newTPC);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void testStringPermissions() {
|
||||
System.out.println(StringPermission.spR);
|
||||
System.out.println(StringPermission.optionsR);
|
||||
|
||||
String testParse = "pouf[Text=coucou].wow[Quoi=\"Hmm\",bou=2].incroyable.ducul[coucou=genial,super=cool]";
|
||||
System.out.println(StringPermission.parse(testParse));
|
||||
|
||||
}
|
||||
|
||||
public static void testDiscordRead() throws LoginException, InterruptedException, Exception {
|
||||
JDA jda = JDABuilder.createDefault("",GatewayIntent.GUILD_MEMBERS,GatewayIntent.values()).build();
|
||||
jda.awaitReady();
|
||||
|
||||
Guild g = jda.getGuildById(222947179017404416L);
|
||||
|
||||
Map<StringPermission,Map<String,Val>> specs = new HashMap<>();
|
||||
|
||||
List<Role> roles = g.getRoles();
|
||||
|
||||
List<Member> membres = g.loadMembers().get();
|
||||
System.out.println("Membres: "+membres);
|
||||
|
||||
Set<StringPermission> defaultGiven = g.getPublicRole().getPermissions().stream()
|
||||
.map(p -> StringPermission.parse(p.getName())).
|
||||
collect(Collectors.toSet());
|
||||
|
||||
Map<String,List<Inheritance>> inheritance = membres.stream().collect(Collectors.toMap(
|
||||
m -> "M"+m.getUser().getName()+"#"+m.getUser().getDiscriminator(),
|
||||
m -> m.getRoles().stream().map(r -> new Inheritance("R"+r.getName(), TPermissionContext.InheritancePolicy.ALL))
|
||||
.collect(Collectors.toList())));
|
||||
|
||||
// for (int i = 1; i < roles.size(); i++) {
|
||||
// inheritance.put("R"+roles.get(i).getName(), List.of(new Inheritance("R"+roles.get(i-1).getName(),TPermissionContext.InheritancePolicy.ALL)));
|
||||
// }
|
||||
|
||||
for(Role r : roles) {
|
||||
for(Permission p : r.getPermissions()) {
|
||||
StringPermission sp = StringPermission.parse(p.getName());
|
||||
if(!specs.containsKey(sp))
|
||||
specs.put(sp, new HashMap<>());
|
||||
specs.get(sp).put("R"+r.getName(), Val.GRANTED);
|
||||
}
|
||||
}
|
||||
// for(Member m : membres) {
|
||||
// for(Permission p : m.getPermissions()) {
|
||||
// StringPermission sp = StringPermission.parse(p.getName());
|
||||
// if(!specs.containsKey(sp))
|
||||
// specs.put(sp, new HashMap<>());
|
||||
// specs.get(sp).put("M"+m.getUser().getName()+"#"+m.getUser().getDiscriminator(), Val.GRANTED);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
TPermissionContext tpc = new TPermissionContext(defaultGiven, specs, inheritance);
|
||||
|
||||
if(tpc.anyCycle())
|
||||
throw new IllegalStateException();
|
||||
System.out.println(tpc);
|
||||
|
||||
FileManager.writeToFile(new File("discordout.ods"), tpc);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
370
src/com/bernard/permissions/tableured/FileManager.java
Normal file
370
src/com/bernard/permissions/tableured/FileManager.java
Normal file
@ -0,0 +1,370 @@
|
||||
package com.bernard.permissions.tableured;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.bernard.permissions.StringPermission;
|
||||
import com.bernard.permissions.tableured.TPermissionContext.Inheritance;
|
||||
import com.bernard.permissions.tableured.TPermissionContext.InheritancePolicy;
|
||||
import com.bernard.permissions.tableured.TPermissionContext.Val;
|
||||
import com.sun.star.beans.PropertyValue;
|
||||
import com.sun.star.beans.XPropertySet;
|
||||
import com.sun.star.comp.helper.Bootstrap;
|
||||
import com.sun.star.comp.helper.BootstrapException;
|
||||
import com.sun.star.frame.XComponentLoader;
|
||||
import com.sun.star.frame.XStorable;
|
||||
import com.sun.star.lang.XMultiComponentFactory;
|
||||
import com.sun.star.sheet.XConditionalFormat;
|
||||
import com.sun.star.sheet.XConditionalFormats;
|
||||
import com.sun.star.sheet.XSheetCellRange;
|
||||
import com.sun.star.sheet.XSheetCellRangeContainer;
|
||||
import com.sun.star.sheet.XSheetCellRanges;
|
||||
import com.sun.star.sheet.XSpreadsheet;
|
||||
import com.sun.star.sheet.XSpreadsheetDocument;
|
||||
import com.sun.star.sheet.XSpreadsheets;
|
||||
import com.sun.star.table.CellRangeAddress;
|
||||
import com.sun.star.table.XCell;
|
||||
import com.sun.star.table.XCellRange;
|
||||
import com.sun.star.table.XColumnRowRange;
|
||||
import com.sun.star.uno.Exception;
|
||||
import com.sun.star.uno.UnoRuntime;
|
||||
import com.sun.star.uno.XComponentContext;
|
||||
import com.sun.star.util.XCloseable;
|
||||
import com.sun.star.util.XMergeable;
|
||||
|
||||
public class FileManager {
|
||||
|
||||
private static XComponentContext xcc_noaccess;
|
||||
|
||||
public static final int MAX_ROW = 3141;
|
||||
public static final int MAX_COL = 3141;
|
||||
|
||||
public static XComponentContext xcc() {
|
||||
if (xcc_noaccess == null) {
|
||||
try {
|
||||
xcc_noaccess = Bootstrap.bootstrap();
|
||||
System.out.println("Connected to a running office ...");
|
||||
} catch (BootstrapException e) {
|
||||
System.err.println("Couldn't connect to office, you won't be able to use ");
|
||||
}
|
||||
}
|
||||
return xcc_noaccess;
|
||||
}
|
||||
|
||||
//TODO: remove «throws Exception» for more precise exceptions
|
||||
|
||||
public static final TPermissionContext readFromFile(File f) throws Exception {
|
||||
|
||||
XComponentContext xcc = xcc();
|
||||
XMultiComponentFactory xmcf;
|
||||
XSpreadsheetDocument xsd;
|
||||
|
||||
xmcf = xcc.getServiceManager();
|
||||
Object object = xmcf.createInstanceWithContext("com.sun.star.frame.Desktop", xcc);
|
||||
XComponentLoader xComponentLoader = qi(XComponentLoader.class,object);
|
||||
PropertyValue[] docLoadProperties = { new PropertyValue() };
|
||||
docLoadProperties[0].Name = "Hidden";
|
||||
docLoadProperties[0].Value = true;
|
||||
xsd = qi(XSpreadsheetDocument.class,
|
||||
xComponentLoader.loadComponentFromURL("file://"+f.getAbsolutePath(), "_blank", 0, docLoadProperties));
|
||||
|
||||
// Variables de sortie:
|
||||
Set<StringPermission> defaultGiven = new HashSet<>();
|
||||
Map<StringPermission, Map<String, Val>> specs = new HashMap<>();
|
||||
Map<String, List<Inheritance>> inheritance = new HashMap<>();
|
||||
|
||||
|
||||
String[] sheetNames = xsd.getSheets().getElementNames();
|
||||
for (int s = 0; s < sheetNames.length; s++) {
|
||||
String sheetName = sheetNames[s];
|
||||
XSpreadsheet sheet = qi(XSpreadsheet.class,xsd.getSheets().getByName(sheetName));
|
||||
|
||||
// Si c'est des permissions
|
||||
if(sheetName.startsWith("Permission")) {
|
||||
|
||||
// Parsing users/groups names
|
||||
int defaultColIndex;
|
||||
List<String> holders = new ArrayList<>();
|
||||
// PermName,…,…,…,Default
|
||||
for(defaultColIndex = 1;!sheet.getCellByPosition(defaultColIndex+1, 0).getFormula().equals("#~END~#") && defaultColIndex<MAX_COL;defaultColIndex++) {
|
||||
holders.add(sheet.getCellByPosition(defaultColIndex, 0).getFormula());
|
||||
}
|
||||
//Devrait être sur la bonne colonne.
|
||||
|
||||
System.out.println(holders);
|
||||
|
||||
// Parsing file names
|
||||
for (int i = 1;!sheet.getCellByPosition(0, i).getFormula().equals("#~END~#") && i<=MAX_ROW; i++) {
|
||||
String perm = sheet.getCellByPosition(0, i).getFormula();
|
||||
if(!perm.isBlank()) {
|
||||
|
||||
Map<String, Val> thisSpec = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
for(int hi=0;hi<holders.size();hi++) {
|
||||
String holder = holders.get(hi);
|
||||
if(holder==null)continue;
|
||||
|
||||
String value = sheet.getCellByPosition(hi+1, i).getFormula();
|
||||
if(!value.isEmpty()) {
|
||||
switch(value.charAt(0)) {
|
||||
case 'x':
|
||||
case 'X':
|
||||
thisSpec.put(holder, TPermissionContext.Val.REVOKED);
|
||||
break;
|
||||
case 'o':
|
||||
case 'O':
|
||||
thisSpec.put(holder, TPermissionContext.Val.GRANTED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
StringPermission perperm = StringPermission.parse(perm);
|
||||
specs.put(perperm, thisSpec);
|
||||
|
||||
//Putting the default
|
||||
String defaultValue = sheet.getCellByPosition(defaultColIndex, i).getFormula();
|
||||
if(!defaultValue.isBlank()) {
|
||||
char defaultValueChar = defaultValue.charAt(0);
|
||||
if(defaultValueChar=='o' || defaultValueChar=='O')
|
||||
defaultGiven.add(perperm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}else if(sheetName.startsWith("Holder")) {
|
||||
|
||||
// Parsing file names
|
||||
for (int i = 1;!sheet.getCellByPosition(0, i).getFormula().equals("#~END~#") && i<=MAX_ROW; i++) {
|
||||
String holder = sheet.getCellByPosition(0, i).getFormula();
|
||||
|
||||
List<Inheritance> inhz = null;
|
||||
|
||||
for(int col = 1;!sheet.getCellByPosition(col, 0).getFormula().equals("#~END~#") && col <= MAX_COL;col++) {
|
||||
String rule = sheet.getCellByPosition(col, i).getFormula();
|
||||
if(!rule.isBlank()) {
|
||||
InheritancePolicy ipol = InheritancePolicy.fromChar(rule.charAt(0));
|
||||
String motherHolderName = (ipol==InheritancePolicy.ALL)?rule:rule.substring(1);
|
||||
|
||||
if(inhz==null)
|
||||
inhz = new ArrayList<>();
|
||||
inhz.add(new Inheritance(motherHolderName, ipol));
|
||||
}
|
||||
}
|
||||
if(inhz!=null)
|
||||
inheritance.put(holder, inhz);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(defaultGiven);
|
||||
System.out.println(specs);
|
||||
System.out.println(inheritance);
|
||||
|
||||
TPermissionContext tpc = new TPermissionContext(defaultGiven, specs, inheritance);
|
||||
if(tpc.anyCycle())
|
||||
throw new IllegalArgumentException("Cycle detected !");
|
||||
|
||||
return tpc;
|
||||
}
|
||||
|
||||
public static final void writeToFile(File f,TPermissionContext tpc) throws Exception {
|
||||
|
||||
XComponentContext xcc = xcc();
|
||||
XMultiComponentFactory xmcf;
|
||||
XSpreadsheetDocument xsd;
|
||||
|
||||
xmcf = xcc.getServiceManager();
|
||||
|
||||
xmcf = xcc.getServiceManager();
|
||||
Object object = xmcf.createInstanceWithContext("com.sun.star.frame.Desktop", xcc);
|
||||
XComponentLoader xcl = qi(XComponentLoader.class,object);
|
||||
|
||||
PropertyValue[] docLoadProperties = { new PropertyValue() };
|
||||
docLoadProperties[0].Name = "Hidden";
|
||||
docLoadProperties[0].Value = true;
|
||||
String baseFile = new File("stringPermissionBase.ods").getAbsolutePath();
|
||||
|
||||
xsd = UnoRuntime.queryInterface(
|
||||
XSpreadsheetDocument.class, xcl.loadComponentFromURL("file://"+baseFile, "_blank", 0, docLoadProperties ));
|
||||
|
||||
XSpreadsheets sheets = xsd.getSheets();
|
||||
|
||||
|
||||
XSpreadsheet permissionsS = qi(XSpreadsheet.class,sheets.getByName("Permissions"));
|
||||
XSpreadsheet permissionsCompleteS = qi(XSpreadsheet.class,sheets.getByName("Permissions-complete"));
|
||||
XSpreadsheet holdersS = qi(XSpreadsheet.class,sheets.getByName("Holders"));
|
||||
|
||||
|
||||
|
||||
|
||||
// ----- Permissions sheet -----
|
||||
|
||||
writePermissionsSheetOutline(tpc, permissionsS,false);
|
||||
|
||||
|
||||
|
||||
|
||||
//TODO: Ajouter le support pour les holders qui commencent par un + ou un - (avec ++=+, +++=++, ...)
|
||||
//TODO: Faire un tri qui «garde la structure du graphe d'héritage»
|
||||
|
||||
// ----- Heritance sheet -----
|
||||
List<String> enfants = tpc.inheritance.keySet().stream().sorted().collect(Collectors.toList());
|
||||
|
||||
holdersS.getCellByPosition(0, 0).setFormula("Holder");;
|
||||
holdersS.getCellByPosition(1, 0).setFormula("Héritages");;
|
||||
System.out.println(tpc.inheritance);
|
||||
int maxCol = 0;
|
||||
for(int i=0;i<enfants.size();i++) {
|
||||
XCell cellEnft = holdersS.getCellByPosition(0,i+1);
|
||||
cellEnft.setFormula(enfants.get(i));
|
||||
qi(XPropertySet.class, cellEnft).setPropertyValue("CellStyle", (i%2==0)?"HeritageHolderEven":"HeritageHolderOdd");
|
||||
|
||||
List<Inheritance> parents = tpc.inheritance.get(enfants.get(i));
|
||||
for (int j = 0; j < parents.size(); j++) {
|
||||
String toWrite = parents.get(j).policy.toChar()+parents.get(j).holder;
|
||||
holdersS.getCellByPosition(j+1, i+1).setFormula(toWrite);
|
||||
}
|
||||
maxCol = Math.max(maxCol, parents.size());
|
||||
}
|
||||
|
||||
// Adding the style on the heritance core.
|
||||
XSheetCellRange xscr = qi(XSheetCellRange.class,holdersS.getCellRangeByPosition(1,0,maxCol,0));
|
||||
System.out.println(xscr);
|
||||
qi(XMergeable.class,xscr).merge(true);
|
||||
for(int i=0;i<enfants.size();i++) {
|
||||
XCellRange cellr = holdersS.getCellRangeByPosition(1,i+1,maxCol,i+1);
|
||||
qi(XPropertySet.class, cellr).setPropertyValue("CellStyle", (i%2==0)?"HeritageEven":"HeritageOdd");
|
||||
}
|
||||
|
||||
// Adding the #~END~# labels
|
||||
holdersS.getCellByPosition(maxCol+1, 0).setFormula("#~END~#");;
|
||||
holdersS.getCellByPosition(0, enfants.size()+1).setFormula("#~END~#");;
|
||||
XCellRange cellrv = holdersS.getCellRangeByPosition(maxCol+1,0,maxCol+1,enfants.size()+1);
|
||||
qi(XPropertySet.class, cellrv).setPropertyValue("CellStyle", "EndLine");
|
||||
XCellRange cellrh = holdersS.getCellRangeByPosition(0,enfants.size()+1,maxCol+1,enfants.size()+1);
|
||||
qi(XPropertySet.class, cellrh).setPropertyValue("CellStyle", "EndLine");
|
||||
|
||||
// Réduis les tailles des dernières colonnes et lignes
|
||||
XColumnRowRange colignes = qi(XColumnRowRange.class,holdersS);
|
||||
qi(XPropertySet.class,colignes.getColumns().getByIndex(maxCol+1)).setPropertyValue("Width", 420);;
|
||||
qi(XPropertySet.class,colignes.getRows().getByIndex(enfants.size()+1)).setPropertyValue("Height", 420);;
|
||||
|
||||
// ----- Permissions-Complete sheet -----
|
||||
// We have two implication graphes: one for holders with inheritance.
|
||||
writePermissionsSheetOutline(tpc, permissionsCompleteS, true);
|
||||
|
||||
|
||||
|
||||
// ----- Écrit le fichier -----
|
||||
|
||||
String fileURL = "file://"+f.getAbsolutePath();
|
||||
XStorable xst = qi(XStorable.class, xsd);
|
||||
|
||||
PropertyValue[] propertyValue = {new PropertyValue()};
|
||||
propertyValue[0] = new com.sun.star.beans.PropertyValue();
|
||||
propertyValue[0].Name = "Overwrite";
|
||||
propertyValue[0].Value = Boolean.TRUE;
|
||||
xst.storeAsURL( fileURL, propertyValue );
|
||||
|
||||
XCloseable xcloz = qi(XCloseable.class, xsd );
|
||||
|
||||
xcloz.close(false);
|
||||
|
||||
}
|
||||
|
||||
private static void writePermissionsSheetOutline(TPermissionContext tpc, XSpreadsheet permissionsS,boolean writeEverything) throws Exception {
|
||||
//C'est de base des Sets, mais sont ordonnés, pour un affichage consistant.
|
||||
List<StringPermission> permissions = Stream.concat(
|
||||
tpc.specs.keySet().stream(),
|
||||
tpc.defaultGiven.stream()
|
||||
).distinct().sorted().collect(Collectors.toList());
|
||||
List<String> permSpecHolders = Stream.concat(tpc.inheritance.keySet().stream(),tpc.specs.values().stream().flatMap(m -> m.keySet().stream())).distinct().sorted().collect(Collectors.toList());
|
||||
//TODO: Find a way to distinct and sorted at the same time
|
||||
for (int i = 0; i < permissions.size(); i++) {
|
||||
XCell cell = permissionsS.getCellByPosition(0,i+1);
|
||||
cell.setFormula(permissions.get(i).toString());
|
||||
qi(XPropertySet.class, cell).setPropertyValue("CellStyle", (i%2==0)?"SpecPermissionEven":"SpecPermissionOdd");
|
||||
}
|
||||
for (int j = 0; j < permSpecHolders.size(); j++) {
|
||||
XCell cell = permissionsS.getCellByPosition(j+1,0);
|
||||
cell.setFormula(permSpecHolders.get(j));
|
||||
qi(XPropertySet.class, cell).setPropertyValue("CellStyle", (j%2==0)?"SpecHolderEven":"SpecHolderOdd");
|
||||
}
|
||||
|
||||
int defaultHolderCol = permSpecHolders.size()+1;
|
||||
XCell celld = permissionsS.getCellByPosition(defaultHolderCol,0);
|
||||
celld.setFormula("#~DEFAULT~#");
|
||||
qi(XPropertySet.class, celld).setPropertyValue("CellStyle", "SpecHolderDefault");
|
||||
|
||||
for(Entry<StringPermission,Map<String,Val>> etry : tpc.specs.entrySet()) {
|
||||
int permIndex = Collections.binarySearch(permissions, etry.getKey());
|
||||
for(Entry<String,Val> ett : etry.getValue().entrySet()) {
|
||||
int hldrIndex = Collections.binarySearch(permSpecHolders, ett.getKey());
|
||||
if(ett.getValue()!=Val.UNSPECIFIED)
|
||||
permissionsS.getCellByPosition(hldrIndex+1,permIndex+1).setFormula(String.valueOf(ett.getValue().toChar()));
|
||||
}
|
||||
}
|
||||
// Writing the DEFAULT column
|
||||
for(int i = 0;i<permissions.size();i++) {
|
||||
StringPermission sp = StringPermission.parse(permissionsS.getCellByPosition(0, i+1).getFormula());
|
||||
if(tpc.defaultGiven.contains(sp))
|
||||
permissionsS.getCellByPosition(defaultHolderCol, i+1).setFormula("o");
|
||||
else if(tpc.defaultGiven.stream().anyMatch(dg -> dg.implies(sp)))
|
||||
permissionsS.getCellByPosition(defaultHolderCol, i+1).setFormula(".");
|
||||
else
|
||||
permissionsS.getCellByPosition(defaultHolderCol, i+1).setFormula("_");
|
||||
}
|
||||
if(writeEverything) {
|
||||
for(int j = 0;j<permSpecHolders.size();j++) {
|
||||
for(int i = 0;i<permissions.size();i++) {
|
||||
if(permissionsS.getCellByPosition(j+1,i+1).getFormula().isBlank())
|
||||
permissionsS.getCellByPosition(j+1,i+1).setFormula(tpc.can(permissions.get(i), permSpecHolders.get(j))?".":"_");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adding the #~END~# labels
|
||||
permissionsS.getCellByPosition(0,permissions.size()+1).setFormula("#~END~#");;
|
||||
permissionsS.getCellByPosition(defaultHolderCol+1, 0).setFormula("#~END~#");;
|
||||
XCellRange cellrv = permissionsS.getCellRangeByPosition(defaultHolderCol+1,0,defaultHolderCol+1,permissions.size()+1);
|
||||
qi(XPropertySet.class, cellrv).setPropertyValue("CellStyle", "EndLine");
|
||||
XCellRange cellrh = permissionsS.getCellRangeByPosition(0,permissions.size()+1,defaultHolderCol+1,permissions.size()+1);
|
||||
qi(XPropertySet.class, cellrh).setPropertyValue("CellStyle", "EndLine");
|
||||
|
||||
// Réduis les tailles des dernières colonnes et lignes
|
||||
XColumnRowRange colignes = qi(XColumnRowRange.class,permissionsS);
|
||||
qi(XPropertySet.class,colignes.getColumns().getByIndex(defaultHolderCol+1)).setPropertyValue("Width", 420);;
|
||||
qi(XPropertySet.class,colignes.getRows().getByIndex(permissions.size()+1)).setPropertyValue("Height", 420);;
|
||||
|
||||
// Applique le formattage conditionel aux données
|
||||
XConditionalFormats formats = qi(XConditionalFormats.class,qi(XPropertySet.class,permissionsS).getPropertyValue("ConditionalFormats"));
|
||||
XConditionalFormat theFormat = formats.getConditionalFormats()[0];
|
||||
XSheetCellRanges applicationRanges = qi(XSheetCellRanges.class,qi(XPropertySet.class,theFormat).getPropertyValue("Range"));
|
||||
XSheetCellRangeContainer applicationRangesP = qi(XSheetCellRangeContainer.class,applicationRanges);
|
||||
applicationRangesP.addRangeAddress(new CellRangeAddress((short)0, 1, 1, defaultHolderCol, permissions.size()), true);
|
||||
qi(XPropertySet.class,theFormat).setPropertyValue("Range", applicationRangesP);
|
||||
}
|
||||
|
||||
public static <T> T qi(Class<T> aType, Object o) {
|
||||
return UnoRuntime.queryInterface(aType, o);
|
||||
}
|
||||
|
||||
}
|
||||
226
src/com/bernard/permissions/tableured/TPermissionContext.java
Normal file
226
src/com/bernard/permissions/tableured/TPermissionContext.java
Normal file
@ -0,0 +1,226 @@
|
||||
package com.bernard.permissions.tableured;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.bernard.math.GraphFunctions;
|
||||
import com.bernard.permissions.PermissionContext;
|
||||
import com.bernard.permissions.StringPermission;
|
||||
|
||||
public class TPermissionContext implements PermissionContext<StringPermission,String> {
|
||||
|
||||
Set<StringPermission> defaultGiven;
|
||||
|
||||
//List<String> permHolder;
|
||||
//List<StringPermission> permissions;
|
||||
//Val[][] specs;
|
||||
|
||||
Map<StringPermission,Map<String,Val>> specs; // <permHolder,<permission,value>>
|
||||
|
||||
Map<String,List<Inheritance>> inheritance; // Par ordre chronologique
|
||||
// Si [0] revoke et [1] grant, alors sera granted
|
||||
|
||||
|
||||
|
||||
|
||||
public TPermissionContext(Set<StringPermission> defaultGiven, Map<StringPermission, Map<String, Val>> specs, Map<String, List<Inheritance>> inheritance) {
|
||||
this.defaultGiven = defaultGiven;
|
||||
this.specs = specs;
|
||||
this.inheritance = inheritance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean can(StringPermission p, String ph) {
|
||||
Val value = isRightGiven(p, ph);
|
||||
if(value==Val.UNSPECIFIED) {
|
||||
for(StringPermission perm : defaultGiven) {
|
||||
if(perm.implies(p))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return value==Val.GRANTED;
|
||||
}
|
||||
|
||||
public Val isRightGiven(StringPermission p, String ph) {
|
||||
|
||||
for(StringPermission perm : specs.keySet()) {
|
||||
if(perm.implies(p) && specs.get(perm).get(ph)==Val.GRANTED)
|
||||
return Val.GRANTED;
|
||||
if(p.implies(perm) && specs.get(perm).get(ph)==Val.REVOKED)
|
||||
return Val.REVOKED;
|
||||
}
|
||||
|
||||
if(!inheritance.containsKey(ph))
|
||||
return Val.UNSPECIFIED;
|
||||
|
||||
// Here, the permission is neither specifically given or revoked to this user.
|
||||
// Let's check the parents.
|
||||
List<Inheritance> inhz = inheritance.get(ph);
|
||||
|
||||
//Ordonné, car les premiers héritages sont prioritaires.
|
||||
for(Inheritance ancetre: inhz) {
|
||||
Val value = isRightGiven(p, ancetre.holder);
|
||||
if(value == Val.UNSPECIFIED)
|
||||
continue; // Cet ancetre n'a pas de spécification pour cette permission, on passe.
|
||||
if(ancetre.policy==InheritancePolicy.ALL
|
||||
|| (ancetre.policy==InheritancePolicy.GRANT_ALL && value==Val.GRANTED)
|
||||
|| (ancetre.policy==InheritancePolicy.REVOKE_ALL && value==Val.REVOKED))
|
||||
return value; // != UNSPECIFIED
|
||||
//Sinon, on ne sait pas.
|
||||
}
|
||||
|
||||
return Val.UNSPECIFIED;
|
||||
}
|
||||
|
||||
|
||||
public boolean anyCycle() {
|
||||
return GraphFunctions.anyCycle(inheritance, i -> i.holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((defaultGiven == null) ? 0 : defaultGiven.hashCode());
|
||||
result = prime * result + ((inheritance == null) ? 0 : inheritance.hashCode());
|
||||
result = prime * result + ((specs == null) ? 0 : specs.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)//FIXME: This doesnt work ...
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TPermissionContext other = (TPermissionContext) obj;
|
||||
if (defaultGiven == null) {
|
||||
if (other.defaultGiven != null)
|
||||
return false;
|
||||
} else if (!defaultGiven.equals(other.defaultGiven))
|
||||
return false;
|
||||
if (inheritance == null) {
|
||||
if (other.inheritance != null)
|
||||
return false;
|
||||
} else if (!inheritance.equals(other.inheritance))
|
||||
return false;
|
||||
if (specs == null) {
|
||||
if (other.specs != null)
|
||||
return false;
|
||||
} else if (!specs.equals(other.specs))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TPermissionContext [defaultGiven=" + defaultGiven + ", specs=" + specs + ", inheritance=" + inheritance
|
||||
+ "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static enum Val {
|
||||
UNSPECIFIED,
|
||||
GRANTED,
|
||||
REVOKED;
|
||||
|
||||
public char toChar() {
|
||||
switch(this) {
|
||||
case GRANTED:
|
||||
return 'o';
|
||||
case REVOKED:
|
||||
return 'x';
|
||||
case UNSPECIFIED:
|
||||
}
|
||||
return (char)0x0;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Inheritance{
|
||||
String holder;
|
||||
InheritancePolicy policy;
|
||||
|
||||
|
||||
|
||||
public Inheritance(String holder, InheritancePolicy policy) {
|
||||
this.holder = holder;
|
||||
this.policy = policy;
|
||||
}
|
||||
|
||||
public String getHolder() {
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((holder == null) ? 0 : holder.hashCode());
|
||||
result = prime * result + ((policy == null) ? 0 : policy.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;
|
||||
Inheritance other = (Inheritance) obj;
|
||||
if (holder == null) {
|
||||
if (other.holder != null)
|
||||
return false;
|
||||
} else if (!holder.equals(other.holder))
|
||||
return false;
|
||||
if (policy != other.policy)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Inheritance [holder=" + holder + ", policy=" + policy + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static enum InheritancePolicy{
|
||||
GRANT_ALL,
|
||||
REVOKE_ALL,
|
||||
ALL;
|
||||
|
||||
public static InheritancePolicy fromChar(char chr) {
|
||||
switch(chr) {
|
||||
case '+':
|
||||
return GRANT_ALL;
|
||||
case '-':
|
||||
return REVOKE_ALL;
|
||||
default:
|
||||
return ALL;
|
||||
}
|
||||
}
|
||||
public char toChar() {
|
||||
switch(this) {
|
||||
case GRANT_ALL:
|
||||
return '+';
|
||||
case REVOKE_ALL:
|
||||
return '-';
|
||||
default:
|
||||
return (char)0x0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
BIN
stringPermissionBase.ods
Normal file
BIN
stringPermissionBase.ods
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user