/**
 * PODD is an OWL ontology database used for scientific project management
 * 
 * Copyright (C) 2009-2013 The University Of Queensland
 * 
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU Affero General Public License as published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 */
package com.github.podd.impl.file;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.openrdf.model.Literal;
import org.openrdf.model.Model;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.vocabulary.RDF;

import com.github.podd.api.file.DataReference;
import com.github.podd.api.file.PoddDataRepository;
import com.github.podd.exception.FileRepositoryIncompleteException;
import com.github.podd.utils.PoddRdfConstants;

/**
 * An abstract implementation of {@link PoddDataRepository} which maintains the <i>alias</i> and
 * <i>types</i>. All internal attributes required to construct a repository configuration are stored
 * in a {@link Model} object and should be validated by sub-classes.
 * 
 * @author kutila
 */
abstract class PoddFileRepositoryImpl<T extends DataReference> implements PoddDataRepository<DataReference>
{
    protected Model model;
    
    protected String alias;
    
    protected final Set<URI> types = Collections.newSetFromMap(new ConcurrentHashMap<URI, Boolean>());
    
    protected Resource aliasUri;
    
    /**
     * Sub-classes should first invoke this from their constructors and subsequently validate
     * sub-class specific attributes exist in the {@link Model}.
     * 
     * @param model
     *            A {@link Model} containing data to construct a File Repository configuration.
     * @throws FileRepositoryIncompleteException
     */
    protected PoddFileRepositoryImpl(final Model model) throws FileRepositoryIncompleteException
    {
        // check that the model contains an "alias" and at least one "type"
        final Model aliasModel = model.filter(null, PoddRdfConstants.PODD_DATA_REPOSITORY_ALIAS, null);
        
        if(aliasModel.isEmpty())
        {
            throw new FileRepositoryIncompleteException(model, "Model did not contain any aliases");
        }
        
        // alias
        this.alias = ((Literal)aliasModel.objects().iterator().next()).getLabel();
        if(this.alias.trim().isEmpty())
        {
            throw new FileRepositoryIncompleteException(model, "File Repository Alias cannot be empty");
        }
        
        this.aliasUri = aliasModel.subjects().iterator().next();
        
        // types
        final Set<Value> typeValues = model.filter(this.aliasUri, RDF.TYPE, null).objects();
        for(final Value value : typeValues)
        {
            if(value instanceof URI)
            {
                this.types.add((URI)value);
            }
        }
        if(this.types.isEmpty())
        {
            throw new FileRepositoryIncompleteException(model, "No File Repository type information found");
        }
        
        this.model = model;
    }
    
    @Override
    public String getAlias()
    {
        return this.alias;
    }
    
    @Override
    public Model getAsModel()
    {
        return this.model;
    }
    
    @Override
    public Set<URI> getTypes()
    {
        return this.types;
    }
    
}

@@ -1100,16 +1100,63 @@
 .Value;%0A
+import org.openrdf.model.impl.LinkedHashModel;%0A
 import o
@@ -2469,24 +2469,82 @@
 ption%0A    %7B%0A
+        this.model = new LinkedHashModel(model);%0A        %0A
         // c
@@ -2636,24 +2636,29 @@
 liasModel = 
+this.
 model.filter
@@ -2816,32 +2816,37 @@
 mpleteException(
+this.
 model, %22Model di
@@ -3091,32 +3091,37 @@
 mpleteException(
+this.
 model, %22File Rep
@@ -3301,16 +3301,21 @@
 alues = 
+this.
 model.fi
@@ -3633,16 +3633,21 @@
 ception(
+this.
 model, %22
@@ -3705,45 +3705,8 @@
   %7D%0A
-        %0A        this.model = model;%0A
     

make a copy of the model to free up the potentially larger model used to create the input model