forked from birkland/ocfl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathocfl.go
153 lines (136 loc) · 4.46 KB
/
ocfl.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package ocfl
import (
"io"
"strings"
"time"
)
// Type names a kind of OCFL entity
type Type int
// OCFL entity type constants, ordered by specificity, e.g. Root > Object
const (
Any Type = iota
File
Version
Object
Intermediate
Root
)
// OCFL version name constants, used in configuring ocfl.Options
const (
NEW = "new"
HEAD = ""
)
// ParseType creates an OCFL type constant from the given string,
// e.g. ocfl.From("Object") == ocfl.Object
func ParseType(name string) Type {
if len(name) > 0 {
switch strings.ToLower(name)[0] {
case 'f':
return File
case 'v':
return Version
case 'o':
return Object
case 'i':
return Intermediate
case 'r':
return Root
}
}
return Any
}
// String representation of an OCFL type constant
func (t Type) String() string {
switch t {
case Any:
return "Any"
case File:
return "File"
case Version:
return "Version"
case Object:
return "Object"
case Intermediate:
return "Intermediate node"
case Root:
return "Root"
default:
return ""
}
}
// EntityRef represents a single OCFL entity.
type EntityRef struct {
ID string // The logical ID of the entity (string, uri, or relative file path)
Addr string // Physical address of the entity (absolute file path or URI)
Parent *EntityRef // Parent of next highest type that isn't an intermediate node (e.g. object parent is root)
Type Type // Type of entity
}
// Coords returns a slice of the logical coordinates of an entity ref, of
// the form {objectID, versionID, logicalFilePath}
func (e EntityRef) Coords() []string {
var coords []string
for ref := &e; ref != nil && ref.Type != Root; ref = ref.Parent {
coords = append([]string{ref.ID}, coords...)
}
return coords
}
// Options for establishing a read/write session on an OCFL object.
//
// A given session is scoped to a single version of an OCFL object.
// That version may be one that already exists, or a uncommitted version.
// Constants ocfl.NEW and ocfl.HEAD are intended to be used with the
// Version field in order to specify the head version regardless of name,
// or an auto-named new version. Otherwise, provide the name of an existing
// version to access its contents.
type Options struct {
Create bool // If true, this will create a new object if one does not exist.
Version string // Desired version, default (zero value) ocfl.HEAD
}
// CommitInfo defines informative text to be included when committing an OCFL version
type CommitInfo struct {
Name string // User name
Address string // Some sort of identifier - e-mail, URL, etc
Message string // Freeform text
Date time.Time
}
// Session allows reading or writing to the an OCFL object.
//
// Each session is bound to a single OCFL object version; either a pre-existing version,
// or an uncommitted new version. New versions contain the content of the previous
// version as a starting point. Drivers may or may not allow writes/commits
// to existing versions.
type Session interface {
Put(lpath string, r io.Reader) error // Put file content at the given logical path
Delete(lpath string) error
// TODO: Move(src, dest string) error
// TODO: Read(lpath string) (io.Reader, error)
Commit(CommitInfo) error
// TODO: Close() error
}
// Opener opens an OCFL object session, potentially allowing reading and writing to it.
type Opener interface {
Open(id string, opts Options) (Session, error) // Open an OCFL object
}
// Walker crawls through a bounded scope of OCFL entities "underneath" a start
// location. Given a location and a desired type, Walker will invoke the provided
// callback any time an entity of the desired type is encountered.
//
// The walk location may either be a single physical address (such as a file path or URI),
// or it may be a sequence of logical OCFL identifiers, such as {objectID, versionID, logicalFilePath}
// When providing logical identifiers, object IDs may be provided on their own, version IDs must be preceded
// by an object ID, and logical file paths must be preceded by the version ID.
//
// If no location is given, the scope of the walk is implied to be the entirety of content under an OCFL root.
type Walker interface {
Walk(desired Select, cb func(EntityRef) error, loc ...string) error
}
// Select indicates desired properties of matching OCFL entities
type Select struct {
Type Type // Desired OCFL type
Head bool // True if desired files or versions must be in the head revision
}
// Driver provides basic OCFL access via some backend
type Driver interface {
Walker
Opener
}