parts = scope.getScopeParts();
+ for (int i = 0, partsSize = parts.size(); i < partsSize; i++) {
+ ScopePart scopePart = parts.get(i);
+ if (!scopePart.equals(this.getScopePart(i))) return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
}
diff --git a/scope/src/main/java/com/gewia/common/scope/impl/MicroServiceScope.java b/scope/src/main/java/com/gewia/common/scope/impl/MicroServiceScope.java
new file mode 100644
index 0000000..736cfde
--- /dev/null
+++ b/scope/src/main/java/com/gewia/common/scope/impl/MicroServiceScope.java
@@ -0,0 +1,106 @@
+package com.gewia.common.scope.impl;
+
+import com.gewia.common.scope.Scope;
+import com.gewia.common.scope.ScopePart;
+import com.gewia.common.scope.impl.util.Limitation;
+import com.gewia.common.scope.impl.util.Mode;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * MicroServiceScope is specified by the following schema: 'microService.topic.mode.limitation.(extra)' .
+ * Example: user.user.write.all - lets the given application/user write/create all users.
+ */
+public class MicroServiceScope extends BasicScope {
+
+ public MicroServiceScope(ScopePart microService, ScopePart topic, Mode mode, Limitation limitation, ScopePart... extra) {
+ super();
+
+ this.addScopePart(microService);
+ this.addScopePart(topic);
+ this.addScopePart(mode.getScopePart());
+ this.addScopePart(limitation.getScopePart());
+
+ for (ScopePart scopePart : extra) this.addScopePart(scopePart);
+ }
+
+ @Override
+ public Scope removeScopePart(int index) {
+ if (index <= 3) throw new UnsupportedOperationException("MicroServiceScopes have to fit the schema.");
+ return super.removeScopePart(index);
+ }
+
+ /**
+ * Gets the currently available scope parts.
+ *
+ *
+ * The returned list is an unmodifiable list, because of the restrictions of {@link MicroServiceScope}.
+ *
+ *
+ * @return all scope parts
+ *
+ * @since 1.0
+ */
+ @Override
+ public List getScopeParts() {
+ return Collections.unmodifiableList(super.getScopeParts());
+ }
+
+
+ /**
+ * Adds the given scopePart at the given index.
+ *
+ * @param scopePart the scope part to add
+ * @param index the index to add the scope part at
+ *
+ * @return this
+ *
+ * @throws IllegalArgumentException if the schema isn't fulfilled (e.g. invalid mode or limitation)
+ *
+ * @since 1.0
+ */
+ @Override
+ public Scope setScopePart(ScopePart scopePart, int index) {
+ if (index == 2 && !Mode.isMode(scopePart)) throw new IllegalArgumentException("Third index has to be a valid mode.");
+ if (index == 3 && !Limitation.isLimitation(scopePart)) throw new IllegalArgumentException("Fourth index has to be a valid limitation");
+
+ return this.setScopePart(scopePart, index);
+ }
+
+ public ScopePart getMicroService() {
+ return this.getScopePart(0);
+ }
+
+ public ScopePart getTopic() {
+ return this.getScopePart(1);
+ }
+
+ public Mode getMode() {
+ return Mode.find(this.getScopePart(2).getContent());
+ }
+
+ public Limitation getLimitation() {
+ return Limitation.find(this.getScopePart(3).getContent());
+ }
+
+ public MicroServiceScope setMicroService(ScopePart microService) {
+ this.setScopePart(microService, 0);
+ return this;
+ }
+
+ public MicroServiceScope setTopic(ScopePart topic) {
+ this.setScopePart(topic, 1);
+ return this;
+ }
+
+ public MicroServiceScope setMode(Mode mode) {
+ this.setScopePart(mode.getScopePart(), 2);
+ return this;
+ }
+
+ public MicroServiceScope setLimitation(Limitation limitation) {
+ this.setScopePart(limitation.getScopePart(), 3);
+ return this;
+ }
+
+}
diff --git a/scope/src/main/java/com/gewia/common/scope/impl/ScopeFactory.java b/scope/src/main/java/com/gewia/common/scope/impl/ScopeFactory.java
index 5c097ac..4c5b479 100644
--- a/scope/src/main/java/com/gewia/common/scope/impl/ScopeFactory.java
+++ b/scope/src/main/java/com/gewia/common/scope/impl/ScopeFactory.java
@@ -1,13 +1,16 @@
package com.gewia.common.scope.impl;
import com.gewia.common.scope.Scope;
+import com.gewia.common.scope.ScopePart;
+import com.gewia.common.scope.impl.util.Limitation;
+import com.gewia.common.scope.impl.util.Mode;
public class ScopeFactory {
/**
- * Creates a {@link BasicScope} with not further restrictions.
+ * Creates a {@link BasicScope} with no further restrictions.
*
- * @return a {@link BasicScope}
+ * @return a new {@link BasicScope}
*
* @since 1.0
*/
@@ -15,4 +18,40 @@ public static Scope createBasicScope() {
return new BasicScope();
}
+ /**
+ * Creates a {@link MicroServiceScope} with it's specified restrictions.
+ *
+ * @param microService the micro service the scope belongs to
+ * @param topic the topic of the scope
+ * @param mode the mode of the scope
+ * @param limitation the limitation of the scope
+ * @param extra extra information
+ *
+ * @return a new {@link MicroServiceScope}
+ *
+ * @see MicroServiceScope
+ * @since 1.0
+ */
+ public static MicroServiceScope createMicroServiceScope(String microService, String topic, Mode mode, Limitation limitation, ScopePart... extra) {
+ return createMicroServiceScope(new ScopePart(microService), new ScopePart(topic), mode, limitation, extra);
+ }
+
+ /**
+ * Creates a {@link MicroServiceScope} with it's specified restrictions.
+ *
+ * @param microService the micro service the scope belongs to
+ * @param topic the topic of the scope
+ * @param mode the mode of the scope
+ * @param limitation the limitation of the scope
+ * @param extra extra information
+ *
+ * @return a new {@link MicroServiceScope}
+ *
+ * @see MicroServiceScope
+ * @since 1.0
+ */
+ public static MicroServiceScope createMicroServiceScope(ScopePart microService, ScopePart topic, Mode mode, Limitation limitation, ScopePart... extra) {
+ return new MicroServiceScope(microService, topic, mode, limitation, extra);
+ }
+
}
diff --git a/scope/src/main/java/com/gewia/common/scope/impl/util/Limitation.java b/scope/src/main/java/com/gewia/common/scope/impl/util/Limitation.java
new file mode 100644
index 0000000..a8574cd
--- /dev/null
+++ b/scope/src/main/java/com/gewia/common/scope/impl/util/Limitation.java
@@ -0,0 +1,29 @@
+package com.gewia.common.scope.impl.util;
+
+import com.gewia.common.scope.ScopePart;
+import lombok.Getter;
+
+public enum Limitation {
+
+ NONE,
+ OWN,
+ SELF,
+ ALL,
+ BETA;
+
+ private static final Limitation[] VALUES = Limitation.values(); // #values() always creates a new copy of the array
+
+ @Getter private final ScopePart scopePart = new ScopePart(this.name().toLowerCase());
+
+ public static Limitation find(String name) {
+ for (Limitation limitation : VALUES)
+ if (limitation.name().equalsIgnoreCase(name)) return limitation;
+
+ return null;
+ }
+
+ public static boolean isLimitation(ScopePart scopePart) {
+ return find(scopePart.getContent()) != null;
+ }
+
+}
diff --git a/scope/src/main/java/com/gewia/common/scope/impl/util/Mode.java b/scope/src/main/java/com/gewia/common/scope/impl/util/Mode.java
new file mode 100644
index 0000000..61f5f95
--- /dev/null
+++ b/scope/src/main/java/com/gewia/common/scope/impl/util/Mode.java
@@ -0,0 +1,27 @@
+package com.gewia.common.scope.impl.util;
+
+import com.gewia.common.scope.ScopePart;
+import lombok.Getter;
+
+public enum Mode {
+
+ READ,
+ WRITE,
+ DELETE;
+
+ private static final Mode[] VALUES = Mode.values(); // #values() always creates a new copy of the array
+
+ @Getter private final ScopePart scopePart = new ScopePart(this.name().toLowerCase());
+
+ public static Mode find(String name) {
+ for (Mode mode : VALUES)
+ if (mode.name().equalsIgnoreCase(name)) return mode;
+
+ return null;
+ }
+
+ public static boolean isMode(ScopePart scopePart) {
+ return find(scopePart.getContent()) != null;
+ }
+
+}
diff --git a/scope/src/test/java/com/gewia/common/scope/test/BasicScopeTest.java b/scope/src/test/java/com/gewia/common/scope/test/BasicScopeTest.java
index aa937fb..f1aeea4 100644
--- a/scope/src/test/java/com/gewia/common/scope/test/BasicScopeTest.java
+++ b/scope/src/test/java/com/gewia/common/scope/test/BasicScopeTest.java
@@ -15,10 +15,12 @@ public void basicCreateAndReadAndDeleteTest() {
Assert.assertEquals("Scope parts size not zero", 0, scope.getScopePartsSize());
Assert.assertEquals("Output not empty", 0, scope.toString().length());
+ scope.addScopeParts("user", "email", "read");
+
Assert.assertEquals(
- "Returned scope not the same",
+ "Scope does not fulfill expectation",
scope,
- scope.addScopeParts("user", "email", "read")
+ ScopeFactory.createBasicScope().addScopeParts("user", "email", "read")
);
Assert.assertEquals("Scope output doesn't match", "user.email.read", scope.toString());
diff --git a/scope/src/test/java/com/gewia/common/scope/test/MicroServiceScopeTest.java b/scope/src/test/java/com/gewia/common/scope/test/MicroServiceScopeTest.java
new file mode 100644
index 0000000..e4909d0
--- /dev/null
+++ b/scope/src/test/java/com/gewia/common/scope/test/MicroServiceScopeTest.java
@@ -0,0 +1,46 @@
+package com.gewia.common.scope.test;
+
+import com.gewia.common.scope.impl.ScopeFactory;
+import com.gewia.common.scope.impl.MicroServiceScope;
+import com.gewia.common.scope.impl.util.Limitation;
+import com.gewia.common.scope.impl.util.Mode;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class MicroServiceScopeTest {
+
+ @Test
+ public void microServiceCreateAndReadAndDeleteTest() {
+ MicroServiceScope scope = ScopeFactory.createMicroServiceScope(
+ "testMicroService",
+ "test",
+ Mode.WRITE,
+ Limitation.ALL
+ );
+
+ Assert.assertFalse("Scope parts empty", scope.getScopeParts().isEmpty());
+ Assert.assertEquals("Scope parts size not zero", 4, scope.getScopePartsSize());
+
+ Assert.assertEquals(
+ "Scope does not fulfill expectation",
+ scope,
+ ScopeFactory.createBasicScope().addScopeParts("testMicroService", "test", "write", "all")
+ );
+
+ Assert.assertEquals("Scope output doesn't match", "testMicroService.test.write.all", scope.toString());
+ Assert.assertEquals("Scope parts do not match size (list access)", 4, scope.getScopeParts().size());
+ Assert.assertEquals("Scope parts do not match size", 4, scope.getScopePartsSize());
+
+ Assert.assertThrows("Scope didn't catch out of bound remove", IndexOutOfBoundsException.class,() -> scope.removeScopePart(4));
+
+ for (int index = 0; index < 3; index++) {
+ int finalIndex = index;
+ Assert.assertThrows("Scope didn't catch not schema-compliant remove", UnsupportedOperationException.class,() -> scope.removeScopePart(finalIndex));
+ }
+
+ Assert.assertEquals("Scope output doesn't match", "testMicroService.test.write.all", scope.toString());
+ Assert.assertEquals("Scope parts do not match size (list access)", 4, scope.getScopeParts().size());
+ Assert.assertEquals("Scope parts do not match size", 4, scope.getScopePartsSize());
+ }
+
+}