/**
* Copyright (C) 2013 Tokanagrammar Team
*
* This is a jigsaw-like puzzle game,
* except each piece is token from a source file,
* and the 'complete picture' is the program.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package edu.umb.cs.entity;
import edu.umb.cs.api.service.DatabaseService;
import edu.umb.cs.parser.BracingStyle;
import edu.umb.cs.parser.ParseException;
import edu.umb.cs.source.Language;
import edu.umb.cs.source.SourceFile;
import edu.umb.cs.source.SourceFiles;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.*;
/**
* @author Vy Thuy Nguyen
* @version 2.0-snapshot Mar 23, 2013
* Last modified:
*/
@Entity
public class Puzzle implements Serializable
{
/**
* The id of the puzzle
*/
@Id
@GeneratedValue (strategy = GenerationType.AUTO)
private long id;
@Transient
private SourceFile srcFile;
@Transient
private List<Hint> cachedHints = null;
@Transient
private final Language langType = Language.JAVA; //TODO: Only support JAVA for now
// This should be settable later
// when we do support other languages
/**
* Relative path to file
*/
private String filePath;
private String prettyName;
private String expectedResult;
private int lang = langType.ordinal();
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE},
fetch = FetchType.EAGER, mappedBy = "puzzle")
private Set<Game> games;
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE},
fetch = FetchType.EAGER, mappedBy = "puzzle")
private Set<Hint> hints;
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
private Category category;
public Puzzle()
{
}
public Puzzle (String path, String expRes, String catName) throws IOException, ParseException
{
File file = new File(path);
if (!file.exists())
throw new IOException("File Not Found");
prettyName = file.getName();
filePath = path;
expectedResult = expRes;
games = new HashSet<>();
hints = new HashSet<>();
category = DatabaseService.findOrCreateCategory(catName);
category.addPuzzle(this);
}
public SourceFile getSourceFile(BracingStyle style) throws ParseException, FileNotFoundException
{
return SourceFiles.getSourceFile(new File(filePath), langType, style);
}
public void addGame(Game g)
{
games.add(g);
}
public Set<Game> getGames()
{
return Collections.unmodifiableSet(games);
}
/**
* After done adding all the hints call DatabaseService.persistPuzzle(<the puzzle>);
* @param h
*/
public void addHint(Hint h)
{
hints.add(h);
}
/**
* Same as add
* @param h
*/
public void removeHint(Hint h)
{
hints.remove(h);
}
public List<Hint> getHints()
{
if (cachedHints == null)
cachedHints = new ArrayList<>(hints);
return cachedHints;
}
public String getExpectedOutput()
{
return expectedResult;
}
@Override
public String toString()
{
return prettyName;
}
@Override
public int hashCode()
{
return filePath.hashCode();
}
@Override
public boolean equals(Object obj)
{
if (obj == null || !(obj instanceof Puzzle))
{
return false;
}
Puzzle other = (Puzzle) obj;
return filePath.equals(other.filePath);
}
}