Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
18
Merge Requests
18
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
jio
Commits
d9e77f60
Commit
d9e77f60
authored
Apr 02, 2015
by
Romain Courteaud
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Drop not used code.
parent
1581dc4a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
0 additions
and
1290 deletions
+0
-1290
src/jio/core/Metadata.js
src/jio/core/Metadata.js
+0
-314
src/jio/core/globals.js
src/jio/core/globals.js
+0
-515
src/jio/core/util.js
src/jio/core/util.js
+0
-461
No files found.
src/jio/core/Metadata.js
deleted
100644 → 0
View file @
1581dc4a
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global exports, deepClone, jsonDeepClone */
/**
* A class to manipulate metadata
*
* @class Metadata
* @constructor
*/
function
Metadata
(
metadata
)
{
if
(
arguments
.
length
>
0
)
{
if
(
metadata
===
null
||
typeof
metadata
!==
'
object
'
||
Array
.
isArray
(
metadata
))
{
throw
new
TypeError
(
"
Metadata(): Optional argument 1 is not an object
"
);
}
this
.
_dict
=
metadata
;
}
else
{
this
.
_dict
=
{};
}
}
Metadata
.
prototype
.
format
=
function
()
{
return
this
.
update
(
this
.
_dict
);
};
Metadata
.
prototype
.
check
=
function
()
{
var
k
;
for
(
k
in
this
.
_dict
)
{
if
(
this
.
_dict
.
hasOwnProperty
(
k
))
{
if
(
k
[
0
]
!==
'
_
'
)
{
if
(
!
Metadata
.
checkValue
(
this
.
_dict
[
k
]))
{
return
false
;
}
}
}
}
return
true
;
};
Metadata
.
prototype
.
update
=
function
(
metadata
)
{
var
k
;
for
(
k
in
metadata
)
{
if
(
metadata
.
hasOwnProperty
(
k
))
{
if
(
k
[
0
]
===
'
_
'
)
{
this
.
_dict
[
k
]
=
jsonDeepClone
(
metadata
[
k
]);
}
else
{
this
.
_dict
[
k
]
=
Metadata
.
normalizeValue
(
metadata
[
k
]);
}
if
(
this
.
_dict
[
k
]
===
undefined
)
{
delete
this
.
_dict
[
k
];
}
}
}
return
this
;
};
Metadata
.
prototype
.
get
=
function
(
key
)
{
return
this
.
_dict
[
key
];
};
Metadata
.
prototype
.
add
=
function
(
key
,
value
)
{
var
i
;
if
(
key
[
0
]
===
'
_
'
)
{
return
this
;
}
if
(
this
.
_dict
[
key
]
===
undefined
)
{
this
.
_dict
[
key
]
=
Metadata
.
normalizeValue
(
value
);
if
(
this
.
_dict
[
key
]
===
undefined
)
{
delete
this
.
_dict
[
key
];
}
return
this
;
}
if
(
!
Array
.
isArray
(
this
.
_dict
[
key
]))
{
this
.
_dict
[
key
]
=
[
this
.
_dict
[
key
]];
}
value
=
Metadata
.
normalizeValue
(
value
);
if
(
value
===
undefined
)
{
return
this
;
}
if
(
!
Array
.
isArray
(
value
))
{
value
=
[
value
];
}
for
(
i
=
0
;
i
<
value
.
length
;
i
+=
1
)
{
this
.
_dict
[
key
][
this
.
_dict
[
key
].
length
]
=
value
[
i
];
}
return
this
;
};
Metadata
.
prototype
.
set
=
function
(
key
,
value
)
{
if
(
key
[
0
]
===
'
_
'
)
{
this
.
_dict
[
key
]
=
JSON
.
parse
(
JSON
.
stringify
(
value
));
}
else
{
this
.
_dict
[
key
]
=
Metadata
.
normalizeValue
(
value
);
}
if
(
this
.
_dict
[
key
]
===
undefined
)
{
delete
this
.
_dict
[
key
];
}
return
this
;
};
Metadata
.
prototype
.
remove
=
function
(
key
)
{
delete
this
.
_dict
[
key
];
return
this
;
};
Metadata
.
prototype
.
forEach
=
function
(
key
,
fun
)
{
var
k
,
i
,
value
,
that
=
this
;
if
(
typeof
key
===
'
function
'
)
{
fun
=
key
;
key
=
undefined
;
}
function
forEach
(
key
,
fun
)
{
value
=
that
.
_dict
[
key
];
if
(
!
Array
.
isArray
(
that
.
_dict
[
key
]))
{
value
=
[
value
];
}
for
(
i
=
0
;
i
<
value
.
length
;
i
+=
1
)
{
if
(
typeof
value
[
i
]
===
'
object
'
)
{
fun
.
call
(
that
,
key
,
deepClone
(
value
[
i
]),
i
);
}
else
{
fun
.
call
(
that
,
key
,
{
'
content
'
:
value
[
i
]},
i
);
}
}
}
if
(
key
===
undefined
)
{
for
(
k
in
this
.
_dict
)
{
if
(
this
.
_dict
.
hasOwnProperty
(
k
))
{
forEach
(
k
,
fun
);
}
}
}
else
{
forEach
(
key
,
fun
);
}
return
this
;
};
Metadata
.
prototype
.
toFullDict
=
function
()
{
var
dict
=
{};
this
.
forEach
(
function
(
key
,
value
,
index
)
{
dict
[
key
]
=
dict
[
key
]
||
[];
dict
[
key
][
index
]
=
value
;
});
return
dict
;
};
Metadata
.
asJsonableValue
=
function
(
value
)
{
switch
(
typeof
value
)
{
case
'
string
'
:
case
'
boolean
'
:
return
value
;
case
'
number
'
:
if
(
isFinite
(
value
))
{
return
value
;
}
return
null
;
case
'
object
'
:
if
(
value
===
null
)
{
return
null
;
}
if
(
value
instanceof
Date
)
{
// XXX this block is to enable phantomjs and browsers compatibility with
// Date.prototype.toJSON when it is a invalid date. In phantomjs, it
// returns `"Invalid Date"` but in browsers it returns `null`. Here, the
// result will always be `null`.
if
(
isNaN
(
value
.
getTime
()))
{
return
null
;
}
}
if
(
typeof
value
.
toJSON
===
'
function
'
)
{
return
Metadata
.
asJsonableValue
(
value
.
toJSON
());
}
return
value
;
// dict, array
// case 'undefined':
default
:
return
null
;
}
};
Metadata
.
isDict
=
function
(
o
)
{
return
typeof
o
===
'
object
'
&&
Object
.
getPrototypeOf
(
o
||
[])
===
Object
.
prototype
;
};
Metadata
.
isContent
=
function
(
c
)
{
return
typeof
c
===
'
string
'
||
(
typeof
c
===
'
number
'
&&
isFinite
(
c
))
||
typeof
c
===
'
boolean
'
;
};
Metadata
.
contentValue
=
function
(
value
)
{
if
(
Array
.
isArray
(
value
))
{
return
Metadata
.
contentValue
(
value
[
0
]);
}
if
(
Metadata
.
isDict
(
value
))
{
return
value
.
content
;
}
return
value
;
};
Metadata
.
normalizeArray
=
function
(
value
)
{
var
i
;
value
=
value
.
slice
();
i
=
0
;
while
(
i
<
value
.
length
)
{
value
[
i
]
=
Metadata
.
asJsonableValue
(
value
[
i
]);
if
(
Metadata
.
isDict
(
value
[
i
]))
{
value
[
i
]
=
Metadata
.
normalizeObject
(
value
[
i
]);
if
(
value
[
i
]
===
undefined
)
{
value
.
splice
(
i
,
1
);
}
else
{
i
+=
1
;
}
}
else
if
(
Metadata
.
isContent
(
value
[
i
]))
{
i
+=
1
;
}
else
{
value
.
splice
(
i
,
1
);
}
}
if
(
value
.
length
===
0
)
{
return
;
}
if
(
value
.
length
===
1
)
{
return
value
[
0
];
}
return
value
;
};
Metadata
.
normalizeObject
=
function
(
value
)
{
var
i
,
count
=
0
,
ok
=
false
,
new_value
=
{};
for
(
i
in
value
)
{
if
(
value
.
hasOwnProperty
(
i
))
{
value
[
i
]
=
Metadata
.
asJsonableValue
(
value
[
i
]);
if
(
Metadata
.
isContent
(
value
[
i
]))
{
new_value
[
i
]
=
value
[
i
];
if
(
new_value
[
i
]
===
undefined
)
{
delete
new_value
[
i
];
}
count
+=
1
;
if
(
i
===
'
content
'
)
{
ok
=
true
;
}
}
}
}
if
(
ok
===
false
)
{
return
;
}
if
(
count
===
1
)
{
return
new_value
.
content
;
}
return
new_value
;
};
Metadata
.
normalizeValue
=
function
(
value
)
{
value
=
Metadata
.
asJsonableValue
(
value
);
if
(
Metadata
.
isContent
(
value
))
{
return
value
;
}
if
(
Array
.
isArray
(
value
))
{
return
Metadata
.
normalizeArray
(
value
);
}
if
(
Metadata
.
isDict
(
value
))
{
return
Metadata
.
normalizeObject
(
value
);
}
};
Metadata
.
checkArray
=
function
(
value
)
{
var
i
;
for
(
i
=
0
;
i
<
value
.
length
;
i
+=
1
)
{
if
(
Metadata
.
isDict
(
value
[
i
]))
{
if
(
!
Metadata
.
checkObject
(
value
[
i
]))
{
return
false
;
}
}
else
if
(
!
Metadata
.
isContent
(
value
[
i
]))
{
return
false
;
}
}
return
true
;
};
Metadata
.
checkObject
=
function
(
value
)
{
var
i
,
ok
=
false
;
for
(
i
in
value
)
{
if
(
value
.
hasOwnProperty
(
i
))
{
if
(
Metadata
.
isContent
(
value
[
i
]))
{
if
(
i
===
'
content
'
)
{
ok
=
true
;
}
}
else
{
return
false
;
}
}
}
if
(
ok
===
false
)
{
return
false
;
}
return
true
;
};
Metadata
.
checkValue
=
function
(
value
)
{
if
(
Metadata
.
isContent
(
value
))
{
return
true
;
}
if
(
Array
.
isArray
(
value
))
{
return
Metadata
.
checkArray
(
value
);
}
if
(
Metadata
.
isDict
(
value
))
{
return
Metadata
.
checkObject
(
value
);
}
return
false
;
};
exports
.
Metadata
=
Metadata
;
src/jio/core/globals.js
deleted
100644 → 0
View file @
1581dc4a
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global uniqueJSONStringify, methodType */
var
defaults
=
{},
constants
=
{};
defaults
.
storage_types
=
{};
constants
.
dcmi_types
=
{
'
Collection
'
:
'
Collection
'
,
'
Dataset
'
:
'
Dataset
'
,
'
Event
'
:
'
Event
'
,
'
Image
'
:
'
Image
'
,
'
InteractiveResource
'
:
'
InteractiveResource
'
,
'
MovingImage
'
:
'
MovingImage
'
,
'
PhysicalObject
'
:
'
PhysicalObject
'
,
'
Service
'
:
'
Service
'
,
'
Software
'
:
'
Software
'
,
'
Sound
'
:
'
Sound
'
,
'
StillImage
'
:
'
StillImage
'
,
'
Text
'
:
'
Text
'
};
// if (dcmi_types.Collection === 'Collection') { is a DCMI type }
// if (typeof dcmi_types[name] === 'string') { is a DCMI type }
constants
.
http_status_text
=
{
"
0
"
:
"
Unknown
"
,
"
550
"
:
"
Internal JIO Error
"
,
"
551
"
:
"
Internal Storage Error
"
,
"
555
"
:
"
Cancelled
"
,
"
Unknown
"
:
"
Unknown
"
,
"
Internal JIO Error
"
:
"
Internal JIO Error
"
,
"
Internal Storage Error
"
:
"
Internal Storage Error
"
,
"
Cancelled
"
:
"
Cancelled
"
,
"
unknown
"
:
"
Unknown
"
,
"
internal_jio_error
"
:
"
Internal JIO Error
"
,
"
internal_storage_error
"
:
"
Internal Storage Error
"
,
"
cancelled
"
:
"
Cancelled
"
,
"
200
"
:
"
Ok
"
,
"
201
"
:
"
Created
"
,
"
204
"
:
"
No Content
"
,
"
205
"
:
"
Reset Content
"
,
"
206
"
:
"
Partial Content
"
,
"
304
"
:
"
Not Modified
"
,
"
400
"
:
"
Bad Request
"
,
"
401
"
:
"
Unauthorized
"
,
"
402
"
:
"
Payment Required
"
,
"
403
"
:
"
Forbidden
"
,
"
404
"
:
"
Not Found
"
,
"
405
"
:
"
Method Not Allowed
"
,
"
406
"
:
"
Not Acceptable
"
,
"
407
"
:
"
Proxy Authentication Required
"
,
"
408
"
:
"
Request Timeout
"
,
"
409
"
:
"
Conflict
"
,
"
410
"
:
"
Gone
"
,
"
411
"
:
"
Length Required
"
,
"
412
"
:
"
Precondition Failed
"
,
"
413
"
:
"
Request Entity Too Large
"
,
"
414
"
:
"
Request-URI Too Long
"
,
"
415
"
:
"
Unsupported Media Type
"
,
"
416
"
:
"
Requested Range Not Satisfiable
"
,
"
417
"
:
"
Expectation Failed
"
,
"
418
"
:
"
I'm a teapot
"
,
"
419
"
:
"
Authentication Timeout
"
,
"
500
"
:
"
Internal Server Error
"
,
"
501
"
:
"
Not Implemented
"
,
"
502
"
:
"
Bad Gateway
"
,
"
503
"
:
"
Service Unavailable
"
,
"
504
"
:
"
Gateway Timeout
"
,
"
507
"
:
"
Insufficient Storage
"
,
"
Ok
"
:
"
Ok
"
,
"
OK
"
:
"
Ok
"
,
"
Created
"
:
"
Created
"
,
"
No Content
"
:
"
No Content
"
,
"
Reset Content
"
:
"
Reset Content
"
,
"
Partial Content
"
:
"
Partial Content
"
,
"
Not Modified
"
:
"
Not Modified
"
,
"
Bad Request
"
:
"
Bad Request
"
,
"
Unauthorized
"
:
"
Unauthorized
"
,
"
Payment Required
"
:
"
Payment Required
"
,
"
Forbidden
"
:
"
Forbidden
"
,
"
Not Found
"
:
"
Not Found
"
,
"
Method Not Allowed
"
:
"
Method Not Allowed
"
,
"
Not Acceptable
"
:
"
Not Acceptable
"
,
"
Proxy Authentication Required
"
:
"
Proxy Authentication Required
"
,
"
Request Timeout
"
:
"
Request Timeout
"
,
"
Conflict
"
:
"
Conflict
"
,
"
Gone
"
:
"
Gone
"
,
"
Length Required
"
:
"
Length Required
"
,
"
Precondition Failed
"
:
"
Precondition Failed
"
,
"
Request Entity Too Large
"
:
"
Request Entity Too Large
"
,
"
Request-URI Too Long
"
:
"
Request-URI Too Long
"
,
"
Unsupported Media Type
"
:
"
Unsupported Media Type
"
,
"
Requested Range Not Satisfiable
"
:
"
Requested Range Not Satisfiable
"
,
"
Expectation Failed
"
:
"
Expectation Failed
"
,
"
I'm a teapot
"
:
"
I'm a teapot
"
,
"
Authentication Timeout
"
:
"
Authentication Timeout
"
,
"
Internal Server Error
"
:
"
Internal Server Error
"
,
"
Not Implemented
"
:
"
Not Implemented
"
,
"
Bad Gateway
"
:
"
Bad Gateway
"
,
"
Service Unavailable
"
:
"
Service Unavailable
"
,
"
Gateway Timeout
"
:
"
Gateway Timeout
"
,
"
Insufficient Storage
"
:
"
Insufficient Storage
"
,
"
ok
"
:
"
Ok
"
,
"
created
"
:
"
Created
"
,
"
no_content
"
:
"
No Content
"
,
"
reset_content
"
:
"
Reset Content
"
,
"
partial_content
"
:
"
Partial Content
"
,
"
not_modified
"
:
"
Not Modified
"
,
"
bad_request
"
:
"
Bad Request
"
,
"
unauthorized
"
:
"
Unauthorized
"
,
"
payment_required
"
:
"
Payment Required
"
,
"
forbidden
"
:
"
Forbidden
"
,
"
not_found
"
:
"
Not Found
"
,
"
method_not_allowed
"
:
"
Method Not Allowed
"
,
"
not_acceptable
"
:
"
Not Acceptable
"
,
"
proxy_authentication_required
"
:
"
Proxy Authentication Required
"
,
"
request_timeout
"
:
"
Request Timeout
"
,
"
conflict
"
:
"
Conflict
"
,
"
gone
"
:
"
Gone
"
,
"
length_required
"
:
"
Length Required
"
,
"
precondition_failed
"
:
"
Precondition Failed
"
,
"
request_entity_too_large
"
:
"
Request Entity Too Large
"
,
"
request-uri_too_long
"
:
"
Request-URI Too Long
"
,
"
unsupported_media_type
"
:
"
Unsupported Media Type
"
,
"
requested_range_not_satisfiable
"
:
"
Requested Range Not Satisfiable
"
,
"
expectation_failed
"
:
"
Expectation Failed
"
,
"
im_a_teapot
"
:
"
I'm a teapot
"
,
"
authentication_timeout
"
:
"
Authentication Timeout
"
,
"
internal_server_error
"
:
"
Internal Server Error
"
,
"
not_implemented
"
:
"
Not Implemented
"
,
"
bad_gateway
"
:
"
Bad Gateway
"
,
"
service_unavailable
"
:
"
Service Unavailable
"
,
"
gateway_timeout
"
:
"
Gateway Timeout
"
,
"
insufficient_storage
"
:
"
Insufficient Storage
"
};
constants
.
http_status
=
{
"
0
"
:
0
,
"
550
"
:
550
,
"
551
"
:
551
,
"
555
"
:
555
,
"
Unknown
"
:
0
,
"
Internal JIO Error
"
:
550
,
"
Internal Storage Error
"
:
551
,
"
Cancelled
"
:
555
,
"
unknown
"
:
0
,
"
internal_jio_error
"
:
550
,
"
internal_storage_error
"
:
551
,
"
cancelled
"
:
555
,
"
200
"
:
200
,
"
201
"
:
201
,
"
204
"
:
204
,
"
205
"
:
205
,
"
206
"
:
206
,
"
304
"
:
304
,
"
400
"
:
400
,
"
401
"
:
401
,
"
402
"
:
402
,
"
403
"
:
403
,
"
404
"
:
404
,
"
405
"
:
405
,
"
406
"
:
406
,
"
407
"
:
407
,
"
408
"
:
408
,
"
409
"
:
409
,
"
410
"
:
410
,
"
411
"
:
411
,
"
412
"
:
412
,
"
413
"
:
413
,
"
414
"
:
414
,
"
415
"
:
415
,
"
416
"
:
416
,
"
417
"
:
417
,
"
418
"
:
418
,
"
419
"
:
419
,
"
500
"
:
500
,
"
501
"
:
501
,
"
502
"
:
502
,
"
503
"
:
503
,
"
504
"
:
504
,
"
507
"
:
507
,
"
Ok
"
:
200
,
"
OK
"
:
200
,
"
Created
"
:
201
,
"
No Content
"
:
204
,
"
Reset Content
"
:
205
,
"
Partial Content
"
:
206
,
"
Not Modified
"
:
304
,
"
Bad Request
"
:
400
,
"
Unauthorized
"
:
401
,
"
Payment Required
"
:
402
,
"
Forbidden
"
:
403
,
"
Not Found
"
:
404
,
"
Method Not Allowed
"
:
405
,
"
Not Acceptable
"
:
406
,
"
Proxy Authentication Required
"
:
407
,
"
Request Timeout
"
:
408
,
"
Conflict
"
:
409
,
"
Gone
"
:
410
,
"
Length Required
"
:
411
,
"
Precondition Failed
"
:
412
,
"
Request Entity Too Large
"
:
413
,
"
Request-URI Too Long
"
:
414
,
"
Unsupported Media Type
"
:
415
,
"
Requested Range Not Satisfiable
"
:
416
,
"
Expectation Failed
"
:
417
,
"
I'm a teapot
"
:
418
,
"
Authentication Timeout
"
:
419
,
"
Internal Server Error
"
:
500
,
"
Not Implemented
"
:
501
,
"
Bad Gateway
"
:
502
,
"
Service Unavailable
"
:
503
,
"
Gateway Timeout
"
:
504
,
"
Insufficient Storage
"
:
507
,
"
ok
"
:
200
,
"
created
"
:
201
,
"
no_content
"
:
204
,
"
reset_content
"
:
205
,
"
partial_content
"
:
206
,
"
not_modified
"
:
304
,
"
bad_request
"
:
400
,
"
unauthorized
"
:
401
,
"
payment_required
"
:
402
,
"
forbidden
"
:
403
,
"
not_found
"
:
404
,
"
method_not_allowed
"
:
405
,
"
not_acceptable
"
:
406
,
"
proxy_authentication_required
"
:
407
,
"
request_timeout
"
:
408
,
"
conflict
"
:
409
,
"
gone
"
:
410
,
"
length_required
"
:
411
,
"
precondition_failed
"
:
412
,
"
request_entity_too_large
"
:
413
,
"
request-uri_too_long
"
:
414
,
"
unsupported_media_type
"
:
415
,
"
requested_range_not_satisfiable
"
:
416
,
"
expectation_failed
"
:
417
,
"
im_a_teapot
"
:
418
,
"
authentication_timeout
"
:
419
,
"
internal_server_error
"
:
500
,
"
not_implemented
"
:
501
,
"
bad_gateway
"
:
502
,
"
service_unavailable
"
:
503
,
"
gateway_timeout
"
:
504
,
"
insufficient_storage
"
:
507
};
constants
.
http_action
=
{
"
0
"
:
"
error
"
,
"
550
"
:
"
error
"
,
"
551
"
:
"
error
"
,
"
555
"
:
"
error
"
,
"
Unknown
"
:
"
error
"
,
"
Internal JIO Error
"
:
"
error
"
,
"
Internal Storage Error
"
:
"
error
"
,
"
Cancelled
"
:
"
error
"
,
"
unknown
"
:
"
error
"
,
"
internal_jio_error
"
:
"
error
"
,
"
internal_storage_error
"
:
"
error
"
,
"
cancelled
"
:
"
error
"
,
"
200
"
:
"
success
"
,
"
201
"
:
"
success
"
,
"
204
"
:
"
success
"
,
"
205
"
:
"
success
"
,
"
206
"
:
"
success
"
,
"
304
"
:
"
success
"
,
"
400
"
:
"
error
"
,
"
401
"
:
"
error
"
,
"
402
"
:
"
error
"
,
"
403
"
:
"
error
"
,
"
404
"
:
"
error
"
,
"
405
"
:
"
error
"
,
"
406
"
:
"
error
"
,
"
407
"
:
"
error
"
,
"
408
"
:
"
error
"
,
"
409
"
:
"
error
"
,
"
410
"
:
"
error
"
,
"
411
"
:
"
error
"
,
"
412
"
:
"
error
"
,
"
413
"
:
"
error
"
,
"
414
"
:
"
error
"
,
"
415
"
:
"
error
"
,
"
416
"
:
"
error
"
,
"
417
"
:
"
error
"
,
"
418
"
:
"
error
"
,
"
419
"
:
"
retry
"
,
"
500
"
:
"
retry
"
,
"
501
"
:
"
error
"
,
"
502
"
:
"
error
"
,
"
503
"
:
"
retry
"
,
"
504
"
:
"
retry
"
,
"
507
"
:
"
error
"
,
"
Ok
"
:
"
success
"
,
"
OK
"
:
"
success
"
,
"
Created
"
:
"
success
"
,
"
No Content
"
:
"
success
"
,
"
Reset Content
"
:
"
success
"
,
"
Partial Content
"
:
"
success
"
,
"
Not Modified
"
:
"
success
"
,
"
Bad Request
"
:
"
error
"
,
"
Unauthorized
"
:
"
error
"
,
"
Payment Required
"
:
"
error
"
,
"
Forbidden
"
:
"
error
"
,
"
Not Found
"
:
"
error
"
,
"
Method Not Allowed
"
:
"
error
"
,
"
Not Acceptable
"
:
"
error
"
,
"
Proxy Authentication Required
"
:
"
error
"
,
"
Request Timeout
"
:
"
error
"
,
"
Conflict
"
:
"
error
"
,
"
Gone
"
:
"
error
"
,
"
Length Required
"
:
"
error
"
,
"
Precondition Failed
"
:
"
error
"
,
"
Request Entity Too Large
"
:
"
error
"
,
"
Request-URI Too Long
"
:
"
error
"
,
"
Unsupported Media Type
"
:
"
error
"
,
"
Requested Range Not Satisfiable
"
:
"
error
"
,
"
Expectation Failed
"
:
"
error
"
,
"
I'm a teapot
"
:
"
error
"
,
"
Authentication Timeout
"
:
"
retry
"
,
"
Internal Server Error
"
:
"
retry
"
,
"
Not Implemented
"
:
"
error
"
,
"
Bad Gateway
"
:
"
error
"
,
"
Service Unavailable
"
:
"
retry
"
,
"
Gateway Timeout
"
:
"
retry
"
,
"
Insufficient Storage
"
:
"
error
"
,
"
ok
"
:
"
success
"
,
"
created
"
:
"
success
"
,
"
no_content
"
:
"
success
"
,
"
reset_content
"
:
"
success
"
,
"
partial_content
"
:
"
success
"
,
"
not_modified
"
:
"
success
"
,
"
bad_request
"
:
"
error
"
,
"
unauthorized
"
:
"
error
"
,
"
payment_required
"
:
"
error
"
,
"
forbidden
"
:
"
error
"
,
"
not_found
"
:
"
error
"
,
"
method_not_allowed
"
:
"
error
"
,
"
not_acceptable
"
:
"
error
"
,
"
proxy_authentication_required
"
:
"
error
"
,
"
request_timeout
"
:
"
error
"
,
"
conflict
"
:
"
error
"
,
"
gone
"
:
"
error
"
,
"
length_required
"
:
"
error
"
,
"
precondition_failed
"
:
"
error
"
,
"
request_entity_too_large
"
:
"
error
"
,
"
request-uri_too_long
"
:
"
error
"
,
"
unsupported_media_type
"
:
"
error
"
,
"
requested_range_not_satisfiable
"
:
"
error
"
,
"
expectation_failed
"
:
"
error
"
,
"
im_a_teapot
"
:
"
error
"
,
"
authentication_timeout
"
:
"
retry
"
,
"
internal_server_error
"
:
"
retry
"
,
"
not_implemented
"
:
"
error
"
,
"
bad_gateway
"
:
"
error
"
,
"
service_unavailable
"
:
"
retry
"
,
"
gateway_timeout
"
:
"
retry
"
,
"
insufficient_storage
"
:
"
error
"
};
constants
.
content_type_re
=
/^
([
a-z
]
+
\/[
a-zA-Z0-9
\+\-\.]
+
)(?:\s
*;
\s
*charset
\s
*=
\s
*
([
a-zA-Z0-9
\-]
+
))?
$/
;
/**
* Function that does nothing
*/
constants
.
emptyFunction
=
function
()
{
return
;
};
defaults
.
job_rule_conditions
=
{};
/**
* Adds some job rule conditions
*/
(
function
()
{
/**
* Compare two jobs and test if they use the same storage description
*
* @param {Object} a The first job to compare
* @param {Object} b The second job to compare
* @return {Boolean} True if equal, else false
*/
function
sameStorageDescription
(
a
,
b
)
{
return
uniqueJSONStringify
(
a
.
storage_spec
)
===
uniqueJSONStringify
(
b
.
storage_spec
);
}
/**
* Compare two jobs and test if they are writers
*
* @param {Object} a The first job to compare
* @param {Object} b The second job to compare
* @return {Boolean} True if equal, else false
*/
function
areWriters
(
a
,
b
)
{
return
methodType
(
a
.
method
)
===
'
writer
'
&&
methodType
(
b
.
method
)
===
'
writer
'
;
}
/**
* Compare two jobs and test if they use metadata only
*
* @param {Object} a The first job to compare
* @param {Object} b The second job to compare
* @return {Boolean} True if equal, else false
*/
function
useMetadataOnly
(
a
,
b
)
{
if
([
'
post
'
,
'
put
'
,
'
get
'
,
'
remove
'
,
'
allDocs
'
].
indexOf
(
a
.
method
)
===
-
1
)
{
return
false
;
}
if
([
'
post
'
,
'
put
'
,
'
get
'
,
'
remove
'
,
'
allDocs
'
].
indexOf
(
b
.
method
)
===
-
1
)
{
return
false
;
}
return
true
;
}
/**
* Compare two jobs and test if they are readers
*
* @param {Object} a The first job to compare
* @param {Object} b The second job to compare
* @return {Boolean} True if equal, else false
*/
function
areReaders
(
a
,
b
)
{
return
methodType
(
a
.
method
)
===
'
reader
'
&&
methodType
(
b
.
method
)
===
'
reader
'
;
}
/**
* Compare two jobs and test if their methods are the same
*
* @param {Object} a The first job to compare
* @param {Object} b The second job to compare
* @return {Boolean} True if equal, else false
*/
function
sameMethod
(
a
,
b
)
{
return
a
.
method
===
b
.
method
;
}
/**
* Compare two jobs and test if their document ids are the same
*
* @param {Object} a The first job to compare
* @param {Object} b The second job to compare
* @return {Boolean} True if equal, else false
*/
function
sameDocumentId
(
a
,
b
)
{
return
a
.
kwargs
.
_id
===
b
.
kwargs
.
_id
;
}
/**
* Test if the jobs have a document id.
*
* @param {Object} a The first job to test
* @param {Object} b The second job to test
* @return {Boolean} True if ids exist, else false
*/
function
haveDocumentIds
(
a
,
b
)
{
if
(
typeof
a
.
kwargs
.
_id
!==
"
string
"
||
a
.
kwargs
.
_id
===
""
)
{
return
false
;
}
if
(
typeof
b
.
kwargs
.
_id
!==
"
string
"
||
b
.
kwargs
.
_id
===
""
)
{
return
false
;
}
return
true
;
}
/**
* Compare two jobs and test if their kwargs are equal
*
* @param {Object} a The first job to compare
* @param {Object} b The second job to compare
* @return {Boolean} True if equal, else false
*/
function
sameParameters
(
a
,
b
)
{
return
uniqueJSONStringify
(
a
.
kwargs
)
===
uniqueJSONStringify
(
b
.
kwargs
);
}
/**
* Compare two jobs and test if their options are equal
*
* @param {Object} a The first job to compare
* @param {Object} b The second job to compare
* @return {Boolean} True if equal, else false
*/
function
sameOptions
(
a
,
b
)
{
return
uniqueJSONStringify
(
a
.
options
)
===
uniqueJSONStringify
(
b
.
options
);
}
defaults
.
job_rule_conditions
=
{
"
sameStorageDescription
"
:
sameStorageDescription
,
"
areWriters
"
:
areWriters
,
"
areReaders
"
:
areReaders
,
"
useMetadataOnly
"
:
useMetadataOnly
,
"
sameMethod
"
:
sameMethod
,
"
sameDocumentId
"
:
sameDocumentId
,
"
sameParameters
"
:
sameParameters
,
"
sameOptions
"
:
sameOptions
,
"
haveDocumentIds
"
:
haveDocumentIds
};
}());
src/jio/core/util.js
deleted
100644 → 0
View file @
1581dc4a
/*jslint indent: 2, maxlen: 80, nomen: true, sloppy: true */
/*global exports, Blob, FileReader, RSVP, hex_sha256, XMLHttpRequest,
constants, console */
/**
* Do not exports these tools unless they are not writable, not configurable.
*/
exports
.
util
=
{};
/**
* Inherits the prototype methods from one constructor into another. The
* prototype of `constructor` will be set to a new object created from
* `superConstructor`.
*
* @param {Function} constructor The constructor which inherits the super
* one
* @param {Function} superConstructor The super constructor
*/
function
inherits
(
constructor
,
superConstructor
)
{
constructor
.
super_
=
superConstructor
;
constructor
.
prototype
=
Object
.
create
(
superConstructor
.
prototype
,
{
"
constructor
"
:
{
"
configurable
"
:
true
,
"
enumerable
"
:
false
,
"
writable
"
:
true
,
"
value
"
:
constructor
}
});
}
/**
* Clones jsonable object in depth
*
* @param {A} object The jsonable object to clone
* @return {A} The cloned object
*/
function
jsonDeepClone
(
object
)
{
var
tmp
=
JSON
.
stringify
(
object
);
if
(
tmp
===
undefined
)
{
return
undefined
;
}
return
JSON
.
parse
(
tmp
);
}
exports
.
util
.
jsonDeepClone
=
jsonDeepClone
;
/**
* Update a dictionary by adding/replacing key values from another dict.
* Enumerable values equal to undefined are also used.
*
* @param {Object} original The dict to update
* @param {Object} other The other dict
* @return {Object} The updated original dict
*/
function
dictUpdate
(
original
,
other
)
{
var
k
;
for
(
k
in
other
)
{
if
(
other
.
hasOwnProperty
(
k
))
{
original
[
k
]
=
other
[
k
];
}
}
return
original
;
}
exports
.
util
.
dictUpdate
=
dictUpdate
;
/**
* Like 'dict.clear()' in python. Delete all dict entries.
*
* @method dictClear
* @param {Object} self The dict to clear
*/
function
dictClear
(
dict
)
{
var
i
;
for
(
i
in
dict
)
{
if
(
dict
.
hasOwnProperty
(
i
))
{
delete
dict
[
i
];
// dictClear(dict);
// break;
}
}
}
exports
.
util
.
dictClear
=
dictClear
;
/**
* Filter a dict to keep only values which keys are in `keys` list.
*
* @param {Object} dict The dict to filter
* @param {Array} keys The key list to keep
*/
function
dictFilter
(
dict
,
keys
)
{
var
i
,
buffer
=
[];
for
(
i
=
0
;
i
<
keys
.
length
;
i
+=
1
)
{
buffer
[
i
]
=
dict
[
keys
[
i
]];
}
dictClear
(
dict
);
for
(
i
=
0
;
i
<
buffer
.
length
;
i
+=
1
)
{
dict
[
keys
[
i
]]
=
buffer
[
i
];
}
}
exports
.
util
.
dictFilter
=
dictFilter
;
/**
* Gets all elements of an array and classifies them in a dict of array.
* Dict keys are element types, and values are list of element of type 'key'.
*
* @param {Array} array The array of elements to pop
* @return {Object} The type dict
*/
function
arrayValuesToTypeDict
(
array
)
{
var
i
,
l
,
type_object
=
{},
type
,
v
;
for
(
i
=
0
,
l
=
array
.
length
;
i
<
l
;
i
+=
1
)
{
v
=
array
[
i
];
type
=
Array
.
isArray
(
v
)
?
"
array
"
:
typeof
v
;
/*jslint ass: true */
(
type_object
[
type
]
=
type_object
[
type
]
||
[]).
push
(
v
);
}
return
type_object
;
}
/**
* Concatenate a `string` `n` times.
*
* @param {String} string The string to concat
* @param {Number} n The number of time to concat
* @return {String} The concatenated string
*/
function
concatStringNTimes
(
string
,
n
)
{
/*jslint plusplus: true */
var
res
=
""
;
while
(
--
n
>=
0
)
{
res
+=
string
;
}
return
res
;
}
/**
* JSON stringify a value. Object keys are sorted in order to make a kind of
* deepEqual thanks to a simple string comparison.
*
* JSON.stringify({"a": "b", "c": "d"}) ===
* JSON.stringify({"c": "d", "a": "b"}) // false
*
* deepEqual({"a": "b", "c": "d"}, {"c": "d", "a": "b"}); // true
*
* uniqueJSONStringify({"a": "b", "c": "d"}) ===
* uniqueJSONStringify({"c": "d", "a": "b"}) // true
*
* @param {Any} value The value to stringify
* @param {Function,Array} [replacer] A function to replace values during parse
* @param {String,Number} [space] Causes the result to be pretty-printed
* @return {String} The unique JSON stringified value
*/
function
uniqueJSONStringify
(
value
,
replacer
,
space
)
{
var
indent
,
key_value_space
=
""
;
if
(
typeof
space
===
"
string
"
)
{
if
(
space
!==
""
)
{
indent
=
space
;
key_value_space
=
"
"
;
}
}
else
if
(
typeof
space
===
"
number
"
)
{
if
(
isFinite
(
space
)
&&
space
>
0
)
{
indent
=
concatStringNTimes
(
"
"
,
space
);
key_value_space
=
"
"
;
}
}
function
uniqueJSONStringifyRec
(
key
,
value
,
deep
)
{
var
i
,
l
,
res
,
my_space
;
if
(
value
&&
typeof
value
.
toJSON
===
"
function
"
)
{
value
=
value
.
toJSON
();
}
if
(
typeof
replacer
===
"
function
"
)
{
value
=
replacer
(
key
,
value
);
}
if
(
indent
)
{
my_space
=
concatStringNTimes
(
indent
,
deep
);
}
if
(
Array
.
isArray
(
value
))
{
res
=
[];
for
(
i
=
0
;
i
<
value
.
length
;
i
+=
1
)
{
res
[
res
.
length
]
=
uniqueJSONStringifyRec
(
i
,
value
[
i
],
deep
+
1
);
if
(
res
[
res
.
length
-
1
]
===
undefined
)
{
res
[
res
.
length
-
1
]
=
"
null
"
;
}
}
if
(
res
.
length
===
0
)
{
return
"
[]
"
;
}
if
(
indent
)
{
return
"
[
\n
"
+
my_space
+
indent
+
res
.
join
(
"
,
\n
"
+
my_space
+
indent
)
+
"
\n
"
+
my_space
+
"
]
"
;
}
return
"
[
"
+
res
.
join
(
"
,
"
)
+
"
]
"
;
}
if
(
typeof
value
===
"
object
"
&&
value
!==
null
)
{
if
(
Array
.
isArray
(
replacer
))
{
res
=
replacer
.
reduce
(
function
(
p
,
c
)
{
p
.
push
(
c
);
return
p
;
},
[]);
}
else
{
res
=
Object
.
keys
(
value
);
}
res
.
sort
();
for
(
i
=
0
,
l
=
res
.
length
;
i
<
l
;
i
+=
1
)
{
key
=
res
[
i
];
res
[
i
]
=
uniqueJSONStringifyRec
(
key
,
value
[
key
],
deep
+
1
);
if
(
res
[
i
]
!==
undefined
)
{
res
[
i
]
=
JSON
.
stringify
(
key
)
+
"
:
"
+
key_value_space
+
res
[
i
];
}
else
{
res
.
splice
(
i
,
1
);
l
-=
1
;
i
-=
1
;
}
}
if
(
res
.
length
===
0
)
{
return
"
{}
"
;
}
if
(
indent
)
{
return
"
{
\n
"
+
my_space
+
indent
+
res
.
join
(
"
,
\n
"
+
my_space
+
indent
)
+
"
\n
"
+
my_space
+
"
}
"
;
}
return
"
{
"
+
res
.
join
(
"
,
"
)
+
"
}
"
;
}
return
JSON
.
stringify
(
value
);
}
return
uniqueJSONStringifyRec
(
""
,
value
,
0
);
}
exports
.
util
.
uniqueJSONStringify
=
uniqueJSONStringify
;
function
makeBinaryStringDigest
(
string
)
{
return
'
sha256-
'
+
hex_sha256
(
string
);
}
exports
.
util
.
makeBinaryStringDigest
=
makeBinaryStringDigest
;
/**
* Acts like `Array.prototype.concat` but does not create a copy of the original
* array. It extends the original array and return it.
*
* @param {Array} array The array to extend
* @param {Any} [args]* Values to add in the array
* @return {Array} The original array
*/
function
arrayExtend
(
array
)
{
// args*
var
i
,
j
;
for
(
i
=
1
;
i
<
arguments
.
length
;
i
+=
1
)
{
if
(
Array
.
isArray
(
arguments
[
i
]))
{
for
(
j
=
0
;
j
<
arguments
[
i
].
length
;
j
+=
1
)
{
array
[
array
.
length
]
=
arguments
[
i
][
j
];
}
}
else
{
array
[
array
.
length
]
=
arguments
[
i
];
}
}
return
array
;
}
exports
.
util
.
arrayExtend
=
arrayExtend
;
/**
* Acts like `Array.prototype.concat` but does not create a copy of the original
* array. It extends the original array from a specific position and return it.
*
* @param {Array} array The array to extend
* @param {Number} position The position where to extend
* @param {Any} [args]* Values to add in the array
* @return {Array} The original array
*/
function
arrayInsert
(
array
,
position
)
{
// args*
var
array_part
=
array
.
splice
(
position
,
array
.
length
-
position
);
arrayExtend
.
apply
(
null
,
arrayExtend
([
],
[
array
],
Array
.
prototype
.
slice
.
call
(
arguments
,
2
)));
return
arrayExtend
(
array
,
array_part
);
}
exports
.
util
.
arrayInsert
=
arrayInsert
;
/**
* Guess if the method is a writer or a reader.
*
* @param {String} method The method name
* @return {String} "writer", "reader" or "unknown"
*/
function
methodType
(
method
)
{
switch
(
method
)
{
case
"
post
"
:
case
"
put
"
:
case
"
putAttachment
"
:
case
"
remove
"
:
case
"
removeAttachment
"
:
case
"
repair
"
:
return
'
writer
'
;
case
"
get
"
:
case
"
getAttachment
"
:
case
"
allDocs
"
:
case
"
check
"
:
return
'
reader
'
;
default
:
return
'
unknown
'
;
}
}
/**
* forEach(array, callback[, thisArg]): Promise
*
* It executes the provided `callback` once for each element of the array with
* an assigned value asynchronously. If the `callback` returns a promise, then
* the function will wait for its fulfillment before executing the next
* iteration.
*
* `callback` is invoked with three arguments:
*
* - the element value
* - the element index
* - the array being traversed
*
* If a `thisArg` parameter is provided to `forEach`, it will be passed to
* `callback` when invoked, for use as its `this` value. Otherwise, the value
* `undefined` will be passed for use as its `this` value.
*
* Unlike `Array.prototype.forEach`, you can stop the iteration by throwing
* something, or by doing a `cancel` to the returned promise if it is
* cancellable promise.
*
* Inspired by `Array.prototype.forEach` from Mozilla Developer Network.
*
* @param {Array} array The array to parse
* @param {Function} callback Function to execute for each element.
* @param {Any} [thisArg] Value to use as `this` when executing `callback`.
* @param {Promise} A new promise.
*/
function
forEach
(
array
,
fn
,
thisArg
)
{
if
(
arguments
.
length
===
0
)
{
throw
new
TypeError
(
"
missing argument 0 when calling function forEach
"
);
}
if
(
!
Array
.
isArray
(
array
))
{
throw
new
TypeError
(
array
+
"
is not an array
"
);
}
if
(
arguments
.
length
===
1
)
{
throw
new
TypeError
(
"
missing argument 1 when calling function forEach
"
);
}
if
(
typeof
fn
!==
"
function
"
)
{
throw
new
TypeError
(
fn
+
"
is not a function
"
);
}
var
cancelled
,
current_promise
=
RSVP
.
resolve
();
return
new
RSVP
.
Promise
(
function
(
done
,
fail
,
notify
)
{
var
i
=
0
;
function
next
()
{
if
(
cancelled
)
{
fail
(
new
Error
(
"
Cancelled
"
));
return
;
}
if
(
i
<
array
.
length
)
{
current_promise
=
current_promise
.
then
(
fn
.
bind
(
thisArg
,
array
[
i
],
i
,
array
));
current_promise
.
then
(
next
,
fail
,
notify
);
i
+=
1
;
return
;
}
done
();
}
next
();
},
function
()
{
cancelled
=
true
;
if
(
typeof
current_promise
.
cancel
===
"
function
"
)
{
current_promise
.
cancel
();
}
});
}
exports
.
util
.
forEach
=
forEach
;
/**
* range(stop, callback): Promise
* range(start, stop[, step], callback): Promise
*
* It executes the provided `callback` once for each step between `start` and
* `stop`. If the `callback` returns a promise, then the function will wait
* for its fulfillment before executing the next iteration.
*
* `callback` is invoked with one argument:
*
* - the index of the step
*
* `start`, `stop` and `step` must be finite numbers. If `step` is not
* provided, then the default step will be `1`. If `start` and `step` are not
* provided, `start` will be `0` and `step` will be `1`.
*
* Inspired by `range()` from Python 3 built-in functions.
*
* range(10, function (index) {
* return notifyIndex(index);
* }).then(onDone, onError, onNotify);
*
* @param {Number} [start=0] The start index
* @param {Number} stop The stop index
* @param {Number} [step=1] One step
* @param {Function} callback Function to execute on each iteration.
* @param {Promise} A new promise with no fulfillment value.
*/
function
range
(
start
,
stop
,
step
,
callback
)
{
var
type_object
,
cancelled
,
current_promise
;
type_object
=
arrayValuesToTypeDict
([
start
,
stop
,
step
,
callback
]);
if
(
type_object
[
"
function
"
].
length
!==
1
)
{
throw
new
TypeError
(
"
range(): only one callback is needed
"
);
}
start
=
type_object
.
number
.
length
;
if
(
start
<
1
)
{
throw
new
TypeError
(
"
range(): 1, 2 or 3 numbers are needed
"
);
}
if
(
start
>
3
)
{
throw
new
TypeError
(
"
range(): only 1, 2 or 3 numbers are needed
"
);
}
callback
=
type_object
[
"
function
"
][
0
];
if
(
start
===
1
)
{
start
=
0
;
stop
=
type_object
.
number
[
0
];
step
=
1
;
}
if
(
start
===
2
)
{
start
=
type_object
.
number
[
0
];
stop
=
type_object
.
number
[
1
];
step
=
1
;
}
if
(
start
===
3
)
{
start
=
type_object
.
number
[
0
];
stop
=
type_object
.
number
[
1
];
step
=
type_object
.
number
[
2
];
if
(
step
===
0
)
{
throw
new
TypeError
(
"
range(): step must not be zero
"
);
}
}
type_object
=
undefined
;
current_promise
=
RSVP
.
resolve
();
return
new
RSVP
.
Promise
(
function
(
done
,
fail
,
notify
)
{
var
i
=
start
,
test
;
function
next
()
{
if
(
cancelled
)
{
fail
(
new
Error
(
"
Cancelled
"
));
return
;
}
test
=
step
>
0
?
i
<
stop
:
i
>
stop
;
if
(
test
)
{
current_promise
=
current_promise
.
then
(
callback
.
bind
(
null
,
i
));
current_promise
.
then
(
next
,
fail
,
notify
);
i
+=
step
;
return
;
}
done
();
}
next
();
},
function
()
{
cancelled
=
true
;
if
(
typeof
current_promise
.
cancel
===
"
function
"
)
{
current_promise
.
cancel
();
}
});
}
exports
.
util
.
range
=
range
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment