store morphology as string rather than as L::F::Structure
[scpubgit/stemmatology.git] / lib / Text / Tradition / Collation / Reading / WordForm.pm
index 6a6b56b..968f205 100644 (file)
@@ -3,6 +3,8 @@ package Text::Tradition::Collation::Reading::WordForm;
 use Lingua::Features::Structure;
 use JSON ();
 use Moose;
+use Text::Tradition::Error;
+use TryCatch;
 
 =head1 NAME
 
@@ -44,22 +46,15 @@ has 'language' => (
        required => 1,
        );
        
-# TODO do we need this?
-has 'form' => (
-       is => 'ro',
-       isa => 'Str',
-       # required => 1,
-       );
-       
 has 'lemma' => (
        is => 'ro',
        isa => 'Str',
        required => 1,
        );
        
-has 'morphology' => (
+has 'morphstr' => (
        is => 'ro',
-       isa => 'Lingua::Features::Structure',
+       isa => 'Str',
        required => 1,
        );
        
@@ -68,13 +63,36 @@ around BUILDARGS => sub {
        my $class = shift;
        my $args = @_ == 1 ? $_[0] : { @_ };
        if( exists $args->{'JSON'} ) {
-               my $data = $args->{'JSON'};
-               my $morph = Lingua::Features::Structure->from_string( $data->{'morphology'} );
-               $data->{'morphology'} = $morph;
-               $args = $data;
+               my @data = split( / \/\/ /, $args->{'JSON'} );
+               # print STDERR "Attempting to parse " . $data[2] . " into structure";
+               $args = { 'language' => $data[0], 'lemma' => $data[1],
+                       'morphstr' => $data[2] };
+       } elsif( exists $args->{'morphology'} ) {
+               # Backwards compat
+               my $mobj = delete $args->{'morphology'};
+               $args->{'morphstr'} = $mobj->to_string()
+                       if ref $mobj;
        }
        $class->$orig( $args );
 };
+
+=head2 morphology
+
+Returns a Lingua::Features::Structure object that corresponds to morphstr.
+
+=cut
+
+sub morphology {
+       my $self = shift;
+       return unless $self->morphstr;
+       my $struct;
+       try {
+               $struct = Lingua::Features::Structure->from_string( $self->morphstr );
+       } catch {
+               throw( "Morphology string " . $self->morphstr . " does not parse" );
+       }
+       return $struct;
+}
        
 =head2 to_string
 
@@ -88,15 +106,21 @@ sub to_string {
        return JSON->new->convert_blessed(1)->encode( $self );
 }
 
+# Rather than spitting it out as a JSON hash, encode it as a string so that
+# the XML serialization doesn't become insane.
 sub TO_JSON {
        my $self = shift;
-       return { 
-               'language' => $self->language,
-               'lemma' => $self->lemma,
-               'morphology' => $self->morphology->to_string
-       };
+       return sprintf( "%s // %s // %s", $self->language, $self->lemma,
+               $self->morphstr );
 }
        
+sub throw {
+       Text::Tradition::Error->throw( 
+               'ident' => 'Wordform error',
+               'message' => $_[0],
+               );
+}
+
 no Moose;
 __PACKAGE__->meta->make_immutable;