forked from riehlegroup/adap-names
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f0a3dbe
commit 803b3bc
Showing
20 changed files
with
2,044 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { File } from "./File"; | ||
import { Directory } from "./Directory"; | ||
|
||
export class BuggyFile extends File { | ||
|
||
constructor(baseName: string, parent: Directory) { | ||
super(baseName, parent); | ||
} | ||
|
||
/** | ||
* Fault injection for homework | ||
* @returns base name, here always "" | ||
*/ | ||
protected doGetBaseName(): string { | ||
this.baseName = ""; | ||
return super.doGetBaseName(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { Exception } from "../common/Exception"; | ||
import { IllegalArgumentException } from "../common/IllegalArgumentException"; | ||
import { ServiceFailureException } from "../common/ServiceFailureException"; | ||
import { Node } from "./Node"; | ||
|
||
export class Directory extends Node { | ||
|
||
protected childNodes: Set<Node> = new Set<Node>(); | ||
|
||
constructor(bn: string, pn: Directory) { | ||
super(bn, pn); | ||
} | ||
|
||
public add(cn: Node): void { | ||
// precondition | ||
IllegalArgumentException.assert( !this.childNodes.has(cn), "Node mustn't exist to add it."); | ||
|
||
this.childNodes.add(cn); | ||
} | ||
|
||
public remove(cn: Node): void { | ||
// precondition | ||
IllegalArgumentException.assert( this.childNodes.has(cn), "Node must exist to delete it."); | ||
|
||
this.childNodes.delete(cn); // Yikes! Should have been called remove | ||
} | ||
|
||
/** | ||
* Returns all nodes in the tree that match bn | ||
* @param bn basename of node being searched for | ||
*/ | ||
public override findNodes(bn: string): Set<Node> { | ||
const s = super.findNodes(bn); | ||
try { | ||
this._findInnerNodes(bn, s); | ||
return s; | ||
} catch (e) { | ||
throw new ServiceFailureException("findNodes() failed", e as Exception); | ||
} | ||
} | ||
|
||
public override _findInnerNodes(bn: string, s: Set<Node>): void { | ||
this.assertClassInvariants(); | ||
|
||
this.childNodes.forEach(node => node._findInnerNodes(bn, s)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { Node } from "./Node"; | ||
import { Directory } from "./Directory"; | ||
import { MethodFailedException } from "../common/MethodFailedException"; | ||
import { IllegalArgumentException } from "../common/IllegalArgumentException"; | ||
|
||
enum FileState { | ||
OPEN, | ||
CLOSED, | ||
DELETED | ||
}; | ||
|
||
export class File extends Node { | ||
|
||
protected state: FileState = FileState.CLOSED; | ||
|
||
constructor(baseName: string, parent: Directory) { | ||
super(baseName, parent); | ||
} | ||
|
||
public open(): void { | ||
IllegalArgumentException.assert( this.doGetFileState() === FileState.CLOSED, "File must be closed"); | ||
// do something | ||
} | ||
|
||
public read(noBytes: number): Int8Array { | ||
let result: Int8Array = new Int8Array(noBytes); | ||
// do something | ||
|
||
let tries: number = 0; | ||
for (let i: number = 0; i < noBytes; i++) { | ||
try { | ||
result[i] = this.readNextByte(); | ||
} catch(ex) { | ||
tries++; | ||
if (ex instanceof MethodFailedException) { | ||
// Oh no! What @todo?! | ||
} | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
protected readNextByte(): number { | ||
return 0; // @todo | ||
} | ||
|
||
public close(): void { | ||
IllegalArgumentException.assert( this.doGetFileState() === FileState.OPEN, "File must be opened"); | ||
// do something | ||
} | ||
|
||
protected doGetFileState(): FileState { | ||
return this.state; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { Node } from "./Node"; | ||
import { Directory } from "./Directory"; | ||
import { IllegalArgumentException } from "../common/IllegalArgumentException"; | ||
|
||
export class Link extends Node { | ||
|
||
protected targetNode: Node | null = null; | ||
|
||
constructor(bn: string, pn: Directory, tn?: Node) { | ||
super(bn, pn); | ||
|
||
if (tn != undefined) { | ||
this.targetNode = tn; | ||
} | ||
} | ||
|
||
public getTargetNode(): Node | null { | ||
this.assertClassInvariants(); | ||
|
||
return this.targetNode; | ||
} | ||
|
||
public setTargetNode(target: Node): void { | ||
this.assertClassInvariants(); | ||
|
||
this.targetNode = target; | ||
} | ||
|
||
public getBaseName(): string { | ||
this.assertClassInvariants(); | ||
|
||
const target = this.ensureTargetNode(this.targetNode); | ||
return target.getBaseName(); | ||
} | ||
|
||
public rename(bn: string): void { | ||
const target = this.ensureTargetNode(this.targetNode); | ||
target.rename(bn); | ||
} | ||
|
||
protected ensureTargetNode(target: Node | null): Node { | ||
IllegalArgumentException.assert( target !== null && target !== undefined, "Target must not be null or undefined"); | ||
|
||
const result: Node = this.targetNode as Node; | ||
return result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import { Exception } from "../common/Exception"; | ||
import { IllegalArgumentException } from "../common/IllegalArgumentException"; | ||
import { InvalidStateException } from "../common/InvalidStateException"; | ||
import { MethodFailedException } from "../common/MethodFailedException"; | ||
import { ServiceFailureException } from "../common/ServiceFailureException"; | ||
|
||
import { Name } from "../names/Name"; | ||
import { Directory } from "./Directory"; | ||
|
||
enum ExceptionType { | ||
PRECONDITION, | ||
POSTCONDITION, | ||
CLASS_INVARIANT, | ||
} | ||
|
||
export class Node { | ||
|
||
protected baseName: string = ""; | ||
protected parentNode: Directory; | ||
|
||
constructor(bn: string, pn: Directory) { | ||
this.assertIsValidBaseName(bn, ExceptionType.PRECONDITION); | ||
|
||
this.doSetBaseName(bn); | ||
this.parentNode = pn; // why oh why do I have to set this | ||
this.initialize(pn); | ||
|
||
// this would be necessary but only without it the homework tests succeed :( | ||
// this.assertClassInvariants(); | ||
} | ||
|
||
protected initialize(pn: Directory): void { | ||
this.parentNode = pn; | ||
this.parentNode.add(this); | ||
} | ||
|
||
public move(to: Directory): void { | ||
this.assertClassInvariants(); | ||
|
||
this.parentNode.remove(this); | ||
to.add(this); | ||
this.parentNode = to; | ||
} | ||
|
||
public getFullName(): Name { | ||
this.assertClassInvariants(); | ||
|
||
const result: Name = this.parentNode.getFullName(); | ||
result.append(this.getBaseName()); | ||
return result; | ||
} | ||
|
||
public getBaseName(): string { | ||
this.assertClassInvariants(); | ||
|
||
return this.doGetBaseName(); | ||
} | ||
|
||
protected doGetBaseName(): string { | ||
return this.baseName; | ||
} | ||
|
||
public rename(bn: string): void { | ||
this.assertClassInvariants(); | ||
|
||
this.assertIsValidBaseName(bn, ExceptionType.PRECONDITION); | ||
|
||
this.doSetBaseName(bn); | ||
} | ||
|
||
protected doSetBaseName(bn: string): void { | ||
this.baseName = bn; | ||
} | ||
|
||
public getParentNode(): Directory { | ||
this.assertClassInvariants(); | ||
|
||
return this.parentNode; | ||
} | ||
|
||
/** | ||
* Returns all nodes in the tree that match bn | ||
* @param bn basename of node being searched for | ||
*/ | ||
public findNodes(bn: string): Set<Node> { | ||
try { | ||
const res = new Set<Node>(); | ||
|
||
this._findInnerNodes(bn, res); | ||
|
||
return res; | ||
} catch (e) { | ||
throw new ServiceFailureException("findNodes() failed", e as Exception); | ||
} | ||
} | ||
|
||
public _findInnerNodes(bn: string, s: Set<Node>) { | ||
this.assertClassInvariants(); | ||
|
||
if (bn === this.doGetBaseName()) s.add(this); | ||
} | ||
|
||
protected assertClassInvariants(): void { | ||
const bn: string = this.doGetBaseName(); | ||
this.assertIsValidBaseName(bn, ExceptionType.CLASS_INVARIANT); | ||
} | ||
|
||
protected assertIsValidBaseName(bn: string, et: ExceptionType): void { | ||
const condition: boolean = (bn !== ""); | ||
switch (et) { | ||
case ExceptionType.PRECONDITION: | ||
IllegalArgumentException.assert(condition, "invalid base name"); | ||
break; | ||
case ExceptionType.POSTCONDITION: | ||
MethodFailedException.assert(condition, "invalid base name"); | ||
break; | ||
case ExceptionType.CLASS_INVARIANT: | ||
InvalidStateException.assert(condition, "invalid base name"); | ||
break; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { IllegalArgumentException } from "../common/IllegalArgumentException"; | ||
import { InvalidStateException } from "../common/InvalidStateException"; | ||
import { MethodFailedException } from "../common/MethodFailedException"; | ||
|
||
import { Name } from "../names/Name"; | ||
import { StringName } from "../names/StringName"; | ||
import { Directory } from "./Directory"; | ||
|
||
enum ExceptionType { | ||
PRECONDITION, | ||
POSTCONDITION, | ||
CLASS_INVARIANT, | ||
} | ||
|
||
export class RootNode extends Directory { | ||
|
||
protected static ROOT_NODE: RootNode = new RootNode(); | ||
|
||
public static getRootNode() { | ||
return this.ROOT_NODE; | ||
} | ||
|
||
constructor() { | ||
super("", new Object as Directory); | ||
} | ||
|
||
protected initialize(pn: Directory): void { | ||
this.parentNode = this; | ||
} | ||
|
||
public getFullName(): Name { | ||
|
||
return new StringName("", '/'); | ||
} | ||
|
||
public move(to: Directory): void { | ||
IllegalArgumentException.assert( false, "Root can't be moved"); | ||
// null operation | ||
} | ||
|
||
protected doSetBaseName(bn: string): void { | ||
this.assertIsValidBaseName(bn, ExceptionType.PRECONDITION); | ||
// null operation | ||
} | ||
|
||
protected assertIsValidBaseName(bn: string, et: ExceptionType): void { | ||
const condition: boolean = (bn === ""); // Root must have "" as base name | ||
switch (et) { | ||
case ExceptionType.PRECONDITION: | ||
IllegalArgumentException.assert(condition, "invalid base name"); | ||
break; | ||
case ExceptionType.POSTCONDITION: | ||
MethodFailedException.assert(condition, "invalid base name"); | ||
break; | ||
case ExceptionType.CLASS_INVARIANT: | ||
InvalidStateException.assert(condition, "invalid base name"); | ||
break; | ||
} | ||
} | ||
|
||
protected assertClassInvariants(): void { | ||
const bn: string = this.doGetBaseName(); | ||
this.assertIsValidBaseName(bn, ExceptionType.CLASS_INVARIANT); | ||
} | ||
|
||
} |
Oops, something went wrong.